# React Hooks 的优势和使用场景
## 1. React Hooks 的优势
### 1.1 简化组件逻辑
Hooks 允许在不编写 class 的情况下使用 state 和其他 React 特性。这使得函数组件能够拥有和类组件相似的能力,同时减少了代码量。
```jsx
// 类组件
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 更好的代码复用
Hooks 解决了高阶组件和渲染属性模式带来的"嵌套地狱"问题,通过自定义 Hook 可以更优雅地复用状态逻辑。
// 自定义 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 将生命周期方法统一为一个 API,使副作用管理更加集中和可预测。
useEffect(() => {
// 相当于 componentDidMount 和 componentDidUpdate
document.title = `You clicked ${count} times`
// 返回的函数相当于 componentWillUnmount
return () => {
document.title = 'React App'
}
}, [count]) // 仅在 count 变化时重新执行
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 则适合更复杂的状态逻辑。
function TodoList() {
const [todos, dispatch] = useReducer(todosReducer, initialTodos)
function handleAdd(text) {
dispatch({ type: 'add', text })
}
// ...
}
2.2 副作用处理
useEffect 适用于数据获取、订阅、手动 DOM 操作等副作用。
function UserProfile({ userId }) {
const [user, setUser] = useState(null)
useEffect(() => {
let isMounted = true
fetchUser(userId).then(data => {
if (isMounted) setUser(data)
})
return () => { isMounted = false }
}, [userId])
// ...
}
2.3 上下文访问
useContext 简化了上下文的使用,避免了多层组件传递 props。
const theme = useContext(ThemeContext)
return <div style={{ background: theme.background }} />
2.4 表单处理
Hooks 可以简化表单状态管理和验证逻辑。
function Form() {
const [values, setValues] = useState({ email: '', password: '' })
const handleChange = e => {
setValues({ ...values, [e.target.name]: e.target.value })
}
// ...
}
2.5 动画和过渡
useSpring 等动画 Hook 可以创建流畅的动画效果。
const props = useSpring({ opacity: 1, from: { opacity: 0 } })
return <animated.div style={props}>I will fade in</animated.div>
3. 最佳实践
- 只在顶层调用 Hooks:不要在循环、条件或嵌套函数中调用 Hooks
- 遵循命名约定:自定义 Hook 应该以 "use" 开头
- 合理拆分 Hooks:将复杂逻辑拆分为多个小 Hook