React Hooks 的优势和使用场景

43 阅读2分钟
# 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'); }
  • 替代高阶组件
    避免组件嵌套地狱,逻辑更扁平化:
    // 替代withRouter等高阶组件
    const location = useLocation();
    const navigate = useNavigate();
    

2. 逻辑关注点分离

  • 副作用管理更清晰

    function UserProfile({ userId }) {
      // 数据获取
      const user = useFetch(`/users/${userId}`);
      // 事件订阅
      useEventListener('resize', handleResize);
      // 动画控制
      useAnimation(show);
    }
    
  • 生命周期聚合
    替代class组件的生命周期方法:

    useEffect(() => {
      // componentDidMount + componentDidUpdate
      return () => { 
        // componentWillUnmount 
      };
    }, [dependencies]);
    

3. 性能优化手段

  • 精细化更新控制

    const memoizedValue = useMemo(() => 
      computeExpensiveValue(a, b), 
      [a, b]
    );
    
    const handleClick = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    
  • 避免重复渲染

    function ExpensiveComponent() {
      const countRef = useRef(0);
      // 不会触发重新渲染
      countRef.current++; 
    }
    

4. 典型使用场景

状态管理

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c+1)}>{count}</button>;
}

副作用处理

function Timer() {
  const [time, setTime] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setTime(t => t+1), 1000);
    return () => clearInterval(id);
  }, []);
  return <div>{time}s</div>;
}

上下文访问

function ThemeButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme.primary }}>OK</button>;
}

5. 最佳实践指南

  1. 顶层调用原则
    Hooks必须在组件顶层调用,不可在条件/循环中使用

  2. 依赖项精确声明
    useEffect/useMemo/useCallback必须正确声明依赖数组

  3. 自定义Hook命名规范
    必须以use开头(如useWindowSize

  4. 性能敏感场景
    对于高频更新状态,优先使用useReducer而非多个useState

  5. 调试技巧
    使用React DevTools可查看Hook调用顺序和当前值

6. 对比Class组件

特性Hooks组件Class组件
代码量减少约30%模板代码多
逻辑复用自定义HookHOC/render props
生命周期useEffect统一处理分散的方法
this绑定问题不存在需要手动绑定
学习曲线需要理解闭包特性需要掌握OOP概念

7. 注意事项

  • 闭包陷阱

    useEffect(() => {
      const timer = setInterval(() => {
        console.log(count); // 总是初始值
      }, 1000);
      return () => clearInterval(timer);
    }, []); // 缺少count依赖
    
  • 执行顺序必须稳定
    错误示例:

    if (condition) {
      useEffect(() => {...}); // 违反调用规则
    }
    
  • 复杂状态处理
    当状态关联复杂时:

    const [state,