# React Hooks 的优势和使用场景## 1. 代码复用性提升**自定义Hook**是Hooks最显著的优势,它允许我们将组件逻辑提取到可重用的函数中。相比传统的HOC或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;}// 在组件中使用function MyComponent() { const { width } = useWindowSize(); return <div>Window width: {width}px</div>;}
2. 逻辑关注点分离
使用多个useEffect
可以按照功能而非生命周期来组织代码,使相关代码保持在一起,提高可维护性。
function UserProfile({ userId }) { // 用户数据获取 const [user, setUser] = useState(null); useEffect(() => { fetchUser(userId).then(setUser); }, [userId]); // 用户活动记录 const [activities, setActivities] = useState([]); useEffect(() => { fetchActivities(userId).then(setActivities); }, [userId]); // 相比class组件的分散逻辑,Hooks使相关代码更集中}
3. 简化复杂组件
useReducer
特别适合管理包含多个子值的复杂state逻辑,比useState更适用于复杂的state操作。
function todoReducer(state, action) { switch (action.type) { case 'add': return [...state, action.payload]; case 'delete': return state.filter(todo => todo.id !== action.payload); default: return state; }}function TodoList() { const [todos, dispatch] = useReducer(todoReducer, []); const addTodo = text => { dispatch({ type: 'add', payload: { id: Date.now(), text } }); }; // 相比多个useState,useReducer能更好管理复杂状态}
4. 性能优化
useMemo
和useCallback
可以避免不必要的计算和子组件重渲染。
function ExpensiveComponent({ list }) { const sortedList = useMemo(() => { return list.sort((a, b) => a.value - b.value); }, [list]); // 只有list变化时才重新计算 const handleClick = useCallback(() => { console.log('Item clicked'); }, []); // 保持函数引用稳定 return <Child onClick={handleClick} data={sortedList} />;}
5. 副作用管理
useEffect
统一了生命周期方法,提供更清晰的副作用管理方式。
function DataFetcher({ url }) { const [data, setData] = useState(null); useEffect(() => { let isMounted = true; const fetchData = async () => { const result = await fetch(url); if (isMounted) setData(await result.json()); }; fetchData(); return () => { isMounted = false; // 清理函数避免内存泄漏 }; }, [url]); // url变化时重新获取}
6. 访问Context更简单
useContext
让Context的使用更加简洁,无需嵌套Consumer。
const ThemeContext = createContext('light');function ThemedButton() { const theme = useContext(ThemeContext); return <button style={{ background: theme }}>按钮</button>;}
7. 替代class组件
Hooks几乎可以覆盖所有class组件的使用场景,使函数组件成为主流选择。
// 替代componentDidMountuseEffect(() => { // 初始化逻辑}, []);// 替代componentDidUpdateuseEffect(() => { // 更新逻辑}, [dependencies]);// 替代componentWillUnmountuseEffect(() => { return () => { // 清理逻辑 };}, []);
8. 更好的TypeScript支持
函数组件配合Hooks能获得更完善的类型推断,减少类型声明代码。