# React Hooks 的优势和使用场景
## 核心优势
1. **逻辑复用更简单**
- 替代高阶组件和render props模式
- 自定义Hook可以提取组件逻辑,实现跨组件复用
```jsx
// 自定义Hook示例
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
const handleResize = () => setSize({
width: window.innerWidth,
height: window.innerHeight
});
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
-
代码组织更清晰
- 相关逻辑可以集中在一起
- 避免生命周期方法中分散的逻辑
// 传统class组件 vs Hooks组件 // Before: 分散在不同生命周期 componentDidMount() { /* 逻辑A + 逻辑B */ } componentDidUpdate() { /* 逻辑A + 逻辑B */ } // After: 相关逻辑集中 useEffect(() => { /* 逻辑A */ }, [deps]); useEffect(() => { /* 逻辑B */ }, [deps]); -
减少组件嵌套
- 消除高阶组件带来的组件层级
- 降低组件树复杂度
-
学习成本更低
- 无需理解class的this绑定问题
- 统一函数组件开发方式
主要使用场景
1. 状态管理
useState 适用于:
- 组件内部简单状态
- 不需要复杂状态逻辑的场景
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Clicked {count} times
</button>
);
}
2. 副作用处理
useEffect 适用于:
- 数据获取
- 事件监听
- DOM操作
useEffect(() => {
const subscription = props.source.subscribe();
return () => subscription.unsubscribe(); // 清理函数
}, [props.source]); // 依赖项
3. 性能优化
useMemo/useCallback 适用于:
- 计算昂贵的值
- 避免不必要的重新渲染
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
4. 复杂状态逻辑
useReducer 适用于:
- 具有复杂状态逻辑的组件
- 需要多个子值的状态对象
function reducer(state, action) {
switch (action.type) {
case 'increment': return {count: state.count + 1};
case 'decrement': return {count: state.count - 1};
default: throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, {count: 0});
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
);
}
5. 访问DOM元素
useRef 适用于:
- 访问DOM节点
- 存储可变值而不触发重新渲染
function TextInput() {
const inputEl = useRef(null);
const focusInput = () => inputEl.current.focus();
return (
<>
<input ref={inputEl} type="text" />
<button onClick={focusInput}>Focus</button>
</>
);
}
最佳实践
-
遵循Hooks规则
- 只在顶层调用Hooks
- 只在React函数中调用Hooks
-
合理拆分Hooks
- 每个Hook负责单一功能
- 复杂逻辑拆分为多个Hooks
-
优化依赖数组
- 确保包含所有依赖项
- 避免不必要的依赖
-
自定义Hook命名
- 使用use前缀
- 语义化命名
-
性能优化
- 合理使用useMemo/useCallback
- 避免在渲染中创建新对象