# React Hooks 的优势和使用场景
## 1. React Hooks 的优势
### 1.1 简化组件逻辑
Hooks 允许在不编写 class 的情况下使用 state 和其他 React 特性。通过将组件拆分为更小的函数,而不是强制按照生命周期方法拆分,使代码更易于理解和维护。
```jsx
// 使用 class
class Counter extends React.Component {
state = { count: 0 };
increment = () => this.setState({ count: this.state.count + 1 });
render() {
return <button onClick={this.increment}>{this.state.count}</button>;
}
}
// 使用 Hooks
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
1.2 更好的代码复用
自定义 Hook 可以提取组件逻辑到可重用的函数中,解决了高阶组件和 render props 带来的"嵌套地狱"问题。
// 自定义 Hook
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;
}
// 在多个组件中使用
function MyComponent() {
const width = useWindowWidth();
return <div>Window width: {width}</div>;
}
1.3 更直观的副作用管理
useEffect 将相关代码组织在一起,比 class 组件中分散在不同生命周期方法中的代码更易于理解。
// 相关逻辑集中在一起
useEffect(() => {
const subscription = props.source.subscribe();
return () => subscription.unsubscribe(); // 清理函数
}, [props.source]); // 依赖数组
1.4 性能优化更简单
useMemo 和 useCallback 提供了更细粒度的性能优化方式,避免了不必要的重新计算和子组件重新渲染。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
2. React Hooks 的使用场景
2.1 状态管理
useState 适用于简单的组件状态管理,useReducer 适合更复杂的状态逻辑。
// 简单状态
const [count, setCount] = useState(0);
// 复杂状态
const [state, dispatch] = useReducer(reducer, initialState);
2.2 副作用处理
useEffect 适用于数据获取、订阅、手动 DOM 操作等副作用。
useEffect(() => {
fetchData().then(data => setData(data));
}, []); // 仅在挂载时执行
2.3 上下文访问
useContext 可以方便地访问 React 上下文,避免了 context consumer 的嵌套。
const theme = useContext(ThemeContext);
return <div style={{ background: theme.background }} />;
2.4 引用 DOM 元素
useRef 可以获取 DOM 元素的引用或保存可变值。
const inputRef = useRef(null);
useEffect(() => inputRef.current.focus(), []);
return <input ref={inputRef} />;
2.5 自定义 Hook
将组件逻辑提取到可重用的自定义 Hook 中。
function useFormInput(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = e => setValue(e.target.value);
return { value, onChange: handleChange };
}
function MyForm() {
const name = useFormInput('Mary');
return <input {...name} />;
}
3. 最佳实践
- 只在顶层调用 Hook:不要在循环、条件或嵌套函数中调用 Hook
- 命名约定:自定义 Hook 名称应以 "use" 开头
- 依赖数组:正确指定
useEffect和useMemo的依赖项 - 拆分复杂逻辑:将复杂组件拆分为多个小 Hook
- 性能优化:合理使用
useMemo和useCallback避免过度渲染
4. 总结
React Hooks 通过提供更直接的 API