2026-03-08 00:41:42
在 React 中创建自定义 Hook 是提升代码复用性和可维护性的关键技巧。以下是经过整理的最佳实践指南,结合示例与核心原则:
一、核心原则明确 Hook 的用途
Hook 用于提取组件逻辑,实现状态与副作用的复用。例如,useCounter 封装计数器逻辑:function useCounter(initialValue = 0) { const [count, setCount] = useState(initialValue); const increment = () => setCount(c => c + 1); return { count, increment };}
遵循命名约定
必须以 use 开头(如 useFetch),React 依赖此规则检查 Hook 调用合法性。
保持纯净性
无副作用:直接修改全局变量或调用 API 需通过 useEffect 处理:function useFetch(url) { const [data, setData] = useState(null); useEffect(() => { fetch(url).then(res => res.json()).then(setData); }, [url]); return data;}
组合现有 Hook
复用 React 内置 Hook(如 useState + useEffect)实现复杂逻辑:function useLocalStorage(key, initialValue) { const [value, setValue] = useState(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initialValue; }); useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue];}
高可复用性
参数化设计:通过参数适配不同场景(如 useCounter(10) 设置初始值)。
最小依赖:避免绑定特定 UI 或业务逻辑。
文档与测试
文档示例:/ * @param {string} key - LocalStorage 键名 * @param {*} initialValue - 默认值 * @returns {[*, Function]} [value, setValue] */function useLocalStorage(key, initialValue) { /* ... */ }
测试要点:test('useLocalStorage 持久化数据', () => { const { result, waitForNextUpdate } = renderHook(() => useLocalStorage('test', 'default') ); act(() => result.current[1]('new')); expect(localStorage.getItem('test')).toBe('"new"');});
依赖项控制
使用 useCallback 避免不必要的重新创建:function useAsync(asyncFn) { const memoizedFn = useCallback(asyncFn, []); // ...其他逻辑}
Hook 组合模式
将多个 Hook 组合为领域特定 Hook(如 useAuth 整合用户状态与登录逻辑)。
违反 Hook 规则
❌ 错误:在条件语句中调用 Hook
✅ 正确:始终在顶层调用 Hook
过度抽象
避免为一次性逻辑创建 Hook,保持简单性。
遵循以上原则可构建出高质量的自定义 Hook:
示例完整流程:
通过系统化应用这些技巧,可以显著提升 React 应用的代码质量和开发效率。