# React Hooks 的优势和使用场景
## 1. 代码复用性提升
- **自定义Hook封装逻辑**
```jsx
// 封装数据获取逻辑
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData);
}, [url]);
return data;
}
// 多处复用
function ComponentA() {
const data = useFetch('/api/a');
}
function ComponentB() {
const data = useFetch('/api/b');
}
相比HOC/render props模式,自定义Hook能更自然地复用状态逻辑
2. 逻辑关注点分离
- 按功能组织代码
相比class组件将相同逻辑分散在不同生命周期,Hooks允许按功能聚合相关代码function UserProfile() { // 用户数据逻辑 const [user, setUser] = useState(null); useEffect(() => { /* 获取用户数据 */ }, []); // 主题设置逻辑 const [theme, setTheme] = useTheme(); // 订阅逻辑 useSubscription(); }
3. 简化复杂组件
- 状态管理更直观
使用useState+useEffect组合可以替代this.setState+生命周期方法的复杂交互// 表单处理 function Form() { const [values, setValues] = useState({}); const handleChange = useCallback((e) => { setValues(prev => ({...prev, [e.target.name]: e.target.value})); }, []); // 自动保存逻辑 useDebounceEffect(() => { saveToServer(values); }, 1000, [values]); }
4. 性能优化更精准
- 细粒度依赖控制
通过useMemo/useCallback可以精确控制重渲染和计算开销function ProductPage({ productId }) { // 只在productId变化时重新计算 const product = useMemo(() => fetchProduct(productId), [productId]); // 稳定的事件处理函数 const addToCart = useCallback(() => { dispatch({ type: 'ADD', product }); }, [product]); }
5. 渐进式采用策略
- 新旧代码兼容
支持在现有class组件中逐步引入Hooksclass OldComponent extends React.Component { // 原有逻辑保持不变 } function NewFeature() { // 新功能使用Hooks开发 const [state, setState] = useState(); return <OldComponent newProp={state} />; }
6. 常见使用场景
-
数据获取
function usePosts() { const [posts, setPosts] = useState([]); useEffect(() => { fetch('/posts').then(res => setPosts(res.data)); }, []); return posts; } -
DOM操作
function useClickOutside(ref, callback) { useEffect(() => { function handleClick(e) { if (ref.current && !ref.current.contains(e.target)) { callback(); } } document.addEventListener('mousedown', handleClick); return () => document.removeEventListener('mousedown', handleClick); }, [ref, callback]); } -
动画控制
function useAnimation(duration) { const [progress, setProgress] = useState(0); useEffect(() => { const start = Date.now(); const frame = () => { const elapsed = Date.now() - start; setProgress(Math.min(elapsed / duration, 1)); if (elapsed < duration) requestAnimationFrame(frame); }; requestAnimationFrame(frame); }, [duration]); return progress; }
7. 最佳实践
-
顶层调用Hooks
// ✅ 正确 function Component() { const [state] = useState(); useEffect(() => {}); } // ❌ 错误 if (condition) { useEffect(() => {}); // 违反规则 } -
合理拆分Hook
// 推荐:每个Hook负责单一功能 function useUser() { /* 用户相关逻辑 */ }