# React Hooks 的优势和使用场景
## 核心优势
1. **简化组件逻辑**
- 将相关逻辑聚合到独立 Hook 中,告别生命周期方法的分散
- 示例:将数据获取和状态管理合并为自定义 Hook
```javascript
function useUserData(userId) {
const [data, setData] = useState(null);
useEffect(() => {
fetchUser(userId).then(setData);
}, [userId]);
return data;
}
-
更好的代码复用
- 突破 HOC 和 render props 的嵌套限制
- 自定义 Hook 可被多个组件共享
// 多个组件共用窗口尺寸监听 function useWindowSize() { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight }); useEffect(() => { const handler = () => setSize({ width: window.innerWidth, height: window.innerHeight }); window.addEventListener('resize', handler); return () => window.removeEventListener('resize', handler); }, []); return size; } -
更直观的状态管理
- useState 提供更清晰的状态更新方式
- 避免 this.setState 的合并问题
// 传统 class 组件 state = { count: 0 }; handleClick = () => this.setState({ count: this.state.count + 1 }); // Hook 版本 const [count, setCount] = useState(0); const handleClick = () => setCount(count + 1);
主要使用场景
-
状态逻辑复用
- 表单处理、动画控制等可提取为自定义 Hook
function useFormInput(initialValue) { const [value, setValue] = useState(initialValue); const handleChange = (e) => setValue(e.target.value); return { value, onChange: handleChange }; } -
副作用管理
- 数据获取、订阅、DOM 操作等副作用
useEffect(() => { const subscription = dataSource.subscribe(); return () => subscription.unsubscribe(); }, [dataSource]); -
性能优化
- useMemo 和 useCallback 避免不必要的计算和渲染
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]); -
跨组件状态共享
- 配合 Context API 实现轻量级状态管理
const ThemeContext = createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar() { const theme = useContext(ThemeContext); return <div>{theme}</div>; }
最佳实践
-
Hook 使用规则
- 只在 React 函数组件顶层调用 Hook
- 不要在循环、条件或嵌套函数中调用 Hook
-
自定义 Hook 规范
- 命名以 use 开头
- 内部可以调用其他 Hook
function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); // ... return isOnline; } -
性能优化技巧
- 合理设置依赖数组
- 复杂组件拆分为多个小 Hook
function useUser(userId) { const [user, setUser] = useState(null); useEffect(() => { fetchUser(userId).then(setUser); }, [userId]); return user; }
注意事项
-
Class 组件对比
- 生命周期方法对应关系:
- constructor → useState
- componentDidMount → useEffect(fn, [])
- componentDidUpdate → useEffect(fn)
- componentWillUnmount → useEffect(() => { return fn }, [])
- 生命周期方法对应关系:
-
常见误区
- 过度使用 useEffect("依赖项地狱")
- 忽略 cleanup 函数导致内存泄漏
// 错误示例:缺少 cleanup useEffect(() => { socket.on('message', handler); }, []); // 正确写法 useEffect(() => { socket.on('message', handler);