[ PROMPT_NODE_25276 ]
hooks
[ SKILL_DOCUMENTATION ]
# Hook TypeScript 模式
针对 useState, useRef, useReducer, useContext 及自定义 Hook 的类型安全模式。
## useState
类型推断适用于简单类型;联合类型/null 需要显式定义类型。
typescript
// 类型推断有效
const [count, setCount] = useState(0); // number
const [name, setName] = useState(''); // string
const [items, setItems] = useState([]); // 空数组需显式定义
// 联合类型/null 需显式定义
const [user, setUser] = useState(null);
const [status, setStatus] = useState('idle');
// 复杂的初始状态
type FormData = { name: string; email: string };
const [formData, setFormData] = useState({
name: '',
email: '',
});
// 惰性初始化
const [data, setData] = useState(() => {
const cached = localStorage.getItem('data');
return cached ? JSON.parse(cached) : defaultData;
});
## useRef
区分 DOM 引用(初始值为 null)与可变值引用(初始值为具体值)。
typescript
// DOM 元素引用 - 初始为 null, .current 为只读
const inputRef = useRef(null);
const buttonRef = useRef(null);
const divRef = useRef(null);
useEffect(() => {
inputRef.current?.focus(); // 使用可选链处理 null
}, []);
// 可变值引用 - 初始非 null, .current 可变
const countRef = useRef(0);
countRef.current += 1; // 无需可选链
const previousValueRef = useRef(undefined);
previousValueRef.current = currentValue;
// 定时器/延时引用
const timeoutRef = useRef<ReturnType>();
const intervalRef = useRef<ReturnType>();
useEffect(() => {
timeoutRef.current = setTimeout(() => {}, 1000);
return () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
};
}, []);
// 动态元素的回调引用
const callbackRef = useCallback((node: HTMLDivElement | null) => {
if (node) {
node.scrollIntoView({ behavior: 'smooth' });
}
}, []);
## useReducer
使用可辨识联合类型定义 Action。
typescript
type State = {
count: number;
status: 'idle' | 'loading' | 'success' | 'error';
error?: string;
};
type Action =
| { type: 'increment' }
| { type: 'decrement' }
| { type: 'set'; payload: number }
| { type: 'setStatus'; payload: State['status'] }
| { type: 'setError'; payload: string };
function reducer(state: State, action: Action): State {
switch (action.type) {