# React Hooks 的优势和使用场景
## 一、React Hooks 核心优势
1. **逻辑复用更简单**
- 告别高阶组件和render props的嵌套地狱
- 自定义Hook可以提取状态逻辑,实现真正的功能复用
```jsx
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
-
代码组织更清晰
- 相关逻辑可以集中在一起
- 告别生命周期方法的强制拆分
// 传统class组件 componentDidMount() { /* 初始化A */ } componentDidUpdate() { /* 更新A */ } componentWillUnmount() { /* 清理A */ } // Hooks方式 useEffect(() => { // 初始化A return () => { /* 清理A */ } }, [/* A的依赖 */]); -
学习成本更低
- 只需掌握useState/useEffect等少量API
- 不用再理解this绑定问题
二、常用Hooks使用场景
1. useState - 状态管理
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Clicked {count} times
</button>
);
}
2. useEffect - 副作用处理
useEffect(() => {
const subscription = props.source.subscribe();
return () => subscription.unsubscribe(); // 清理函数
}, [props.source]); // 依赖数组
3. useContext - 跨组件通信
const themes = { light: { foreground: '#000' } };
const ThemeContext = createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.light}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme.foreground }}>按钮</button>;
}
4. useReducer - 复杂状态逻辑
function reducer(state, action) {
switch (action.type) {
case 'increment': return {count: state.count + 1};
default: throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, {count: 0});
return (
<button onClick={() => dispatch({type: 'increment'})}>
{state.count}
</button>
);
}
三、进阶Hooks应用
-
性能优化
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]); -
DOM操作
function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => inputEl.current.focus(); return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus</button> </> ); } -
自定义Hook示例
function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); useEffect(() => { const handleStatusChange = status => setIsOnline(status.isOnline); ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange); return () => ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange); }, [friendID]); return isOnline; }
四、最佳实践
-
Hooks使用规则
- 只在React函数组件或自定义Hook中调用
- 只在最顶层调用,不要在循环、条件或嵌套函数中调用
-
性能优化建议
- 合理使用依赖数组
- 复杂计算使用useMemo
- 避免在渲染函数中直接创建对象/函数
-
代码组织建议
- 相关逻辑组织在同一个useEffect
- 复杂组件拆分为多个小Hook
- 提取可复用逻辑到自定义Hook
五、与传统方案的对比
| 特性 | Class组件 | Hooks组件 |
|---|---|---|
| 代码量 | 多 | 少30%-50% |
| 逻辑复用 | 困难 | 简单 |
| 学习曲线 | 陡峭 | 平缓 |
| 性能优化 | 需要手动 | 内置优化 |
| 测试友好度 | 一般 | 更好 |
六、适用场景总结
-
推荐使用Hooks的场景
- 新项目开发
- 需要逻辑复用的组件
- 复杂状态管理的组件
- 需要更好性能优化的组件
-
仍需谨慎的场景
- 现有Class组件的稳定维护
- 需要getSnapshotBeforeUpdate等特殊生命周期的场景
- 尚未完全支持Hooks的第三方库集成
Hooks代表了React未来的发展方向,虽然不强制迁移现有代码,但新项目强烈推荐采用Hooks方案。