React中的常用类型
在 React 函数组件中使用 TypeScript 时,有若干常用且关键的类型声明,它们帮助你获得完整的类型安全、自动补全和错误检查。
- React 项目是通过
@types/react、@types/react-dom类型声明包,来提供类型的。 - 这些包 CRA 已帮我们安装好(
react-app-env.d.ts),直接用即可。
✅ 1. 函数组件本身的类型
// TS 会自动推断 props 类型和返回值(JSX.Element)
const MyComponent = ({ name, age }: { name: string; age: number }) => {
return <div>Hello, {name}!</div>;
};
✅ 2. Props 类型定义(最核心!)
推荐:使用 interface 或 type
interface Props {
title: string;
count?: number; // 可选属性
onClick: () => void; // 必需回调
status: 'loading' | 'idle' | 'success'; // 字面量联合类型
}
const MyComponent = ({ title, count = 0, onClick, status }: Props) => {
return (
<button disabled={status === 'loading'} onClick={onClick}>
{title} ({count})
</button>
);
};
💡 最佳实践:
- 使用
interface(便于扩展)- 明确区分可选(
?)和必需属性- 回调函数使用
() => void或(arg: T) => void
✅ 3. 事件处理函数类型
常见事件类型:
import React, { ChangeEvent, MouseEvent, FormEvent } from 'react';
const InputComponent = () => {
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value);
};
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
};
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} />
<button onClick={handleClick}>Submit</button>
</form>
);
};
🔑 常用事件类型:
ChangeEvent<T>:输入框、选择框等值变化MouseEvent<T>:点击、悬停等KeyboardEvent<T>:键盘事件FormEvent<T>:表单提交FocusEvent<T>:聚焦/失焦
✅ 4. Ref 类型
使用 useRef:
import { useRef, useEffect } from 'react';
const FocusInput = () => {
// HTMLInputElement 是 input 元素的类型
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus(); // 安全调用
}, []);
return <input ref={inputRef} />;
};
自定义组件 Ref(配合 forwardRef):
import { forwardRef, Ref } from 'react';
interface CustomInputProps {
value: string;
onChange: (val: string) => void;
}
// 自定义组件暴露的 ref 类型(通常是 HTML 元素或实例方法)
const CustomInput = forwardRef<HTMLInputElement, CustomInputProps>(
({ value, onChange }, ref) => {
return <input ref={ref} value={value} onChange={e => onChange(e.target.value)} />;
}
);
✅ 5. Context 类型
import { createContext, useContext } from 'react';
interface ThemeContextType {
theme: 'light' | 'dark';
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | null>(null);
// 自定义 hook 封装
const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within ThemeProvider');
}
return context;
};
💡 注意:
createContext的初始值类型要与实际 Provider 提供的值一致。
✅ 6. State 类型(useState)
import { useState } from 'react';
const Counter = () => {
// TS 自动推断 count 为 number
const [count, setCount] = useState(0);
// 显式声明复杂状态
interface User {
id: string;
name: string;
}
const [user, setUser] = useState<User | null>(null);
};
✅ 技巧:对复杂对象或可能为
null的状态,显式标注泛型更安全。
✅ 7. 自定义 Hook 类型
// 返回值类型自动推断,也可显式声明
const useLocalStorage = <T>(key: string, initialValue: T): [T, (value: T) => void] => {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value: T) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue];
};
// 使用
const [name, setName] = useLocalStorage<string>('name', 'Alice');
✅ 8. Children 类型(如果需要显式声明)
虽然通常不需要(因为 JSX 自动处理),但如果组件接受 children 且你想显式约束:
interface CardProps {
children: React.ReactNode; // 最通用
// 或更严格:children: string | JSX.Element | (string | JSX.Element)[];
}
const Card = ({ children }: CardProps) => {
return <div className="card">{children}</div>;
};
📌
React.ReactNode是最常用的 children 类型,它包括:
string、numberJSX.Elementnull、undefined、boolean(会被忽略)- 数组(嵌套)
✅ 总结:React 函数组件常用 TS 类型清单
| 场景 | 推荐类型 |
|---|---|
| 组件 Props | interface Props { ... } |
| 事件处理 | ChangeEvent<HTMLInputElement>, MouseEvent<HTMLButtonElement> 等 |
| Refs | useRef<HTMLInputElement>(null) |
| State | useState<number>(0), useState<User | null>(null) |
| Context | createContext<MyContextType | null>(null) |
| Children | React.ReactNode(通常无需显式声明) |
| 自定义 Hook 返回值 | 显式元组类型 [T, (v: T) => void] |