用途
当用户需要以下操作时,可使用本技能:
- 使用 React 内置 Hook(useState、useEffect、useContext、useRef、useMemo、useCallback)
- 创建自定义 Hook 以复用有状态逻辑
- 使用 useReducer 管理复杂状态
- 通过记忆化 Hook 优化组件性能
- 使用 useEffect 处理副作用(数据获取、订阅、定时器)
- 理解并遵循 Hooks 规则
主要能力
本技能提供 React Hooks 的代码生成与指导,覆盖内置 Hook、自定义 Hook 模式、复杂状态管理、性能优化与副作用处理,并强调依赖数组、清理函数与 Hooks 规则的正确使用。
使用方式
工作流程:
- 识别哪种 Hook 最符合用户需求
- 应用 Hooks 规则:只在顶层调用 Hook;只从 React 函数中调用 Hook
- 生成带有正确依赖数组和清理函数的 Hook 代码
- 验证是否存在过期闭包或缺失依赖
1. useState 与 useEffect
import { useState, useEffect } from 'react';
function useUserData(userId: string) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
let cancelled = false;
setLoading(true);
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
if (!cancelled) {
setUser(data);
setLoading(false);
}
})
.catch(err => {
if (!cancelled) {
setError(err);
setLoading(false);
}
});
return () => { cancelled = true; }; // Cleanup on unmount or userId change
}, [userId]);
return { user, loading, error };
}
2. 使用 useReducer 处理复杂状态
import { useReducer } from 'react';
type State = { count: number; step: number };
type Action = { type: 'increment' } | { type: 'decrement' } | { type: 'setStep'; payload: number };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'increment': return { ...state, count: state.count + state.step };
case 'decrement': return { ...state, count: state.count - state.step };
case 'setStep': return { ...state, step: action.payload };
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
3. useMemo 与 useCallback
import { useMemo, useCallback } from 'react';
function FilteredList({ items, filter }: { items: Item[]; filter: string }) {
// Memoize expensive computation
const filtered = useMemo(
() => items.filter(item => item.name.includes(filter)),
[items, filter]
);
// Memoize callback to prevent child re-renders
const handleSelect = useCallback((id: string) => {
console.log('Selected:', id);
}, []);
return <ItemList items={filtered} onSelect={handleSelect} />;
}
4. 自定义 Hook 模式
import { useState, useCallback } from 'react';
function useToggle(initialValue = false): [boolean, () => void] {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue(prev => !prev), []);
return [value, toggle];
}
// Usage
function Modal() {
const [isOpen, toggleOpen] = useToggle(false);
return <>{isOpen && <div>Modal Content</div>}<button onClick={toggleOpen}>Toggle</button></>;
}
适用场景
- 使用内置 Hook 构建组件状态与副作用逻辑
- 抽取可复用的有状态逻辑为自定义 Hook
- 以 useReducer 管理复杂状态转换
- 通过 useMemo、useCallback 优化渲染性能
- 处理数据获取、订阅、定时器等副作用
最佳实践
- 始终在 useEffect 依赖数组中包含所有依赖(使用 ESLint 插件 react-hooks/exhaustive-deps)
- 在 useEffect 返回函数中清理订阅、定时器和监听器
- 自定义 Hook 以 use 前缀命名(如 useAuth、useFetch)
- 绝不在条件、循环或嵌套函数中调用 Hook
- 仅在存在可衡量的性能收益时使用 useCallback 和 useMemo
- 当状态转换复杂时,优先使用 useReducer 而非多个 useState
限制
本技能的具体收费、价格、平台支持等信息暂未提供。
资源
- Hooks 参考:https://react.dev/reference/react
- Hooks 规则:https://react.dev/reference/rules/rules-of-hooks
关键词
React Hooks、useState、useEffect、useContext、useReducer、useMemo、useCallback、useRef、自定义 Hook、Hooks 规则、依赖数组、清理、记忆化