Skip to content
📖预计阅读时长:0 分钟字数:0

React TypeScript 实战

进阶篇第 4 章:掌握 TypeScript 在 React 中的应用。

返回 React学习路线 | 上一章 React-09-状态管理 | 下一章 React-11-性能优化


一、组件类型定义

1.1 函数组件

typescript
// 基本组件
interface ButtonProps {
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
}

function Button({ children, onClick, disabled }: ButtonProps) {
  return (
    <button onClick={onClick} disabled={disabled}>
      {children}
    </button>
  );
}

// 使用 FC(可选,不强制)
const Button: React.FC<ButtonProps> = ({ children, onClick }) => {
  return <button onClick={onClick}>{children}</button>;
};

1.2 Props 类型技巧

typescript
// children 类型
interface Props {
  children: React.ReactNode;      // 任意内容
  children: React.ReactElement;   // 必须是 React 元素
  children: string;               // 只能是字符串
}

// 扩展原生属性
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary';
}

// 组合类型
type ButtonProps = {
  variant?: 'primary' | 'secondary';
} & React.ButtonHTMLAttributes<HTMLButtonElement>;

1.3 泛型组件

typescript
interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
}

function List<T>({ items, renderItem }: ListProps<T>) {
  return <ul>{items.map(renderItem)}</ul>;
}

// 使用
<List
  items={[{ id: 1, name: 'Alice' }]}
  renderItem={(item) => <li key={item.id}>{item.name}</li>}
/>

二、Hooks 类型

2.1 useState

typescript
// 自动推断
const [count, setCount] = useState(0);

// 显式指定
const [user, setUser] = useState<User | null>(null);

// 联合类型
type Status = 'idle' | 'loading' | 'success' | 'error';
const [status, setStatus] = useState<Status>('idle');

2.2 useReducer

typescript
interface State {
  count: number;
  error: string | null;
}

type Action =
  | { type: 'increment' }
  | { type: 'decrement' }
  | { type: 'setError'; payload: string };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'decrement':
      return { ...state, count: state.count - 1 };
    case 'setError':
      return { ...state, error: action.payload };
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0, error: null });

2.3 useRef

typescript
// DOM 引用
const inputRef = useRef<HTMLInputElement>(null);

// 可变值
const timerRef = useRef<number | null>(null);

2.4 useContext

typescript
interface AuthContext {
  user: User | null;
  login: (credentials: Credentials) => Promise<void>;
  logout: () => void;
}

const AuthContext = createContext<AuthContext | null>(null);

function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within AuthProvider');
  }
  return context;
}

三、事件类型

typescript
// 常用事件类型
function Form() {
  const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {};
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {};
  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {};
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {};

  return (
    <form onSubmit={handleSubmit}>
      <input onChange={handleChange} onKeyDown={handleKeyDown} />
      <button onClick={handleClick}>Submit</button>
    </form>
  );
}

四、常用类型速查

类型用途
React.ReactNode任何可渲染内容
React.ReactElementJSX 元素
React.FC<Props>函数组件类型
React.CSSPropertiesstyle 对象
React.MouseEvent<T>鼠标事件
React.ChangeEvent<T>输入变化事件
React.FormEvent<T>表单事件

五、实用技巧

5.1 组件 Props 提取

typescript
// 提取组件的 props 类型
type ButtonProps = React.ComponentProps<typeof Button>;
type InputProps = React.ComponentProps<'input'>;

5.2 Omit 和 Pick

typescript
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

// 排除某些属性
type PublicUser = Omit<User, 'password'>;

// 选取某些属性
type UserCredentials = Pick<User, 'email' | 'password'>;

下一步


#React #TypeScript #类型系统