1. 安装
- create-react-app
- 直接 create-react-app 项目名 —typescript 即可(等同于下面两步操作)
```javascript
// 1. To start a new Create React App project with TypeScript, you can run:
npx create-react-app my-app —template typescript
or
yarn create react-app my-app —template typescript
// 2. To add TypeScript to a Create React App project, first install it: npm install —save typescript @types/node @types/react @types/react-dom @types/jest
or
yarn add typescript @types/node @types/react @types/react-dom @types/jest
<a name="d6ppt"></a>## 2. State 和 Props<a name="WjD1L"></a>### 2.1 Class组件写法- **Component<IProps, IState> 若该组件没有定义IProps,传{} 空对象即可**- **Component<{}, IState>****App.tsx**```javascriptimport React from 'react';import Hello from './components/Hello';function App() {return (<div className="App"><Hello title="标题" age={20} /></div>);}export default App;
components/Hello.tsx
import React, { Component } from 'react';// 通过接口声明propsinterface IProps {title: string;age?: number;}// 通过接口声明stateinterface IState {count: number;}export default class Hello extends Component<IProps, IState> {// 实现statepublic readonly state: Readonly<IState> = {count: 1000,};public handleChange = () => {this.setState({ count: 2000 });};render() {const { title, age } = this.props;const { count } = this.state;return (<div><h2>Hello {title} - age: {age}<div><h3>{count}</h3><button onClick={this.handleChange}>按钮</button></div></h2></div>);}}
2.2 Functional组件写法
- 如果IProps里有对象属性,可以再声明个接口描述这个对象
- 函数组件里**React.FC
这里不需要传IState,因为函数组件里是使用hooks的**
App.tsx
import React from 'react';import { TextFiled } from './components/TextFiled';function App() {return (<div className="App"><TextFiledtext="Hello"person={{ firstName: 'Chenxii', lastName: 'C' }}/></div>);}export default App;
components/TextField.tsx
import React from 'react';interface IPerson {firstName: string;lastName: string;}interface IProps {text: string;ok?: boolean;index?: number;fn?: (bob: string) => void;person?: IPerson;// obj: {// f1: string// }}export const TextFiled: React.FC<IProps> = (props) => {return <div>{props.text}</div>;};
3. Hooks
3.1 useState Hook
export const TextFiled: React.FC<IProps> = (props) => {const [count, setCount] = useState<number | null>(5);setCount(null);return <div>{props.text}</div>;};
interface TextNode {text: string}export const TextFiled: React.FC<IProps> = (props) => {const [count, setCount] = useState<TextNode>({text: "hello"});return <div>{props.text}</div>;};
3.2 useRef Hook + 事件
App.tsx
import React from 'react';import { TextFiled } from './components/TextField';function App() {return (<div className="App"><TextFiledtext="Hello"person={{ firstName: 'Chenxii', lastName: 'C' }}handleChange={e => {....}}/></div>);}export default App;
components/TextField.tsx
import React, { useState, useRef } from 'react';interface IPerson {firstName: string;lastName: string;}interface IProps {text: string;ok?: boolean;index?: number;fn?: (bob: string) => void;person?: IPerson;handleChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;}export const TextFiled: React.FC<IProps> = (props) => {const inputRef = useRef<HTMLInputElement>(null);const divRef = useRef<HTMLDivElement>(null);return (<div ref={divRef}><input ref={inputRef} onChange={props.handleChange} /></div>);};
3.3 useReducer Hook
import React, { useReducer } from 'react';type Actions = { type: 'add'; text: string } | { type: 'remove'; idx: number };interface Todo {text: string;complete: boolean;}type State = Todo[];const TodoReducer = (state: State, action: Actions) => {switch (action.type) {case 'add':return [...state, { text: action.text, complete: false }];case 'remove':return state.filter((_, i) => action.idx !== i);default:return state;}};export const ReducerExample: React.FC = () => {const [todos, dispatch] = useReducer(TodoReducer, []);return (<div>{JSON.stringify(todos)}<buttononClick={() => {dispatch({ type: 'add', text: '...' });}}>+</button></div>);};
4. 事件处理
- 子组件的IProps接口中这样定义方法: onMyClick: (data: string) => void
App.tsx
import React from 'react';import Hello from './components/Hello';function App() {const handleClick = (data: string) => {console.log(data);};return (<div className="App"><Hello title="标题" age={20} onMyClick={handleClick} /></div>);}export default App;
components/Hello.tsx
import React, { Component } from 'react';interface IProps {title: string;age?: number;onMyClick: (data: string) => void;}// 通过接口声明stateinterface IState {count: number;}export default class Hello extends Component<IProps, IState> {// 实现statepublic readonly state: Readonly<IState> = {count: 1000,};public handleChange = () => {this.setState({ count: 2000 });};public handleSendMsg = () => {this.props.onMyClick('child event');};render() {const { title, age } = this.props;const { count } = this.state;return (<div><h2>Hello {title} - age: {age}<div><h3>{count}</h3><button onClick={this.handleChange}>按钮</button><button onClick={this.handleSendMsg}>Send Msg</button></div></h2></div>);}}
