React Hooks 的优势和使用场景

46 阅读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');
  }

相比HOC/render props模式,自定义Hook能更自然地复用状态逻辑

2. 逻辑关注点分离

  • 按功能组织代码
    function UserProfile() {
      // 用户数据逻辑
      const [user, setUser] = useState(null);
      useEffect(() => { /* 获取用户数据 */ }, []);
    
      // 主题设置逻辑
      const [theme, setTheme] = useTheme();
    
      // 订阅逻辑
      useSubscription();
    }
    
    相比class组件将相同逻辑分散在不同生命周期,Hooks允许按功能聚合相关代码

3. 简化复杂组件

  • 状态管理更直观
    // 表单处理
    function Form() {
      const [values, setValues] = useState({});
      const handleChange = useCallback((e) => {
        setValues(prev => ({...prev, [e.target.name]: e.target.value}));
      }, []);
    
      // 自动保存逻辑
      useDebounceEffect(() => {
        saveToServer(values);
      }, 1000, [values]);
    }
    
    使用useState+useEffect组合可以替代this.setState+生命周期方法的复杂交互

4. 性能优化更精准

  • 细粒度依赖控制
    function ProductPage({ productId }) {
      // 只在productId变化时重新计算
      const product = useMemo(() => fetchProduct(productId), [productId]);
    
      // 稳定的事件处理函数
      const addToCart = useCallback(() => {
        dispatch({ type: 'ADD', product });
      }, [product]);
    }
    
    通过useMemo/useCallback可以精确控制重渲染和计算开销

5. 渐进式采用策略

  • 新旧代码兼容
    class OldComponent extends React.Component {
      // 原有逻辑保持不变
    }
    
    function NewFeature() {
      // 新功能使用Hooks开发
      const [state, setState] = useState();
      return <OldComponent newProp={state} />;
    }
    
    支持在现有class组件中逐步引入Hooks

6. 常见使用场景

  1. 数据获取

    function usePosts() {
      const [posts, setPosts] = useState([]);
      useEffect(() => {
        fetch('/posts').then(res => setPosts(res.data));
      }, []);
      return posts;
    }
    
  2. 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]);
    }
    
  3. 动画控制

    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. 最佳实践

  1. 顶层调用Hooks

    // ✅ 正确
    function Component() {
      const [state] = useState();
      useEffect(() => {});
    }
    
    // ❌ 错误
    if (condition) {
      useEffect(() => {}); // 违反规则
    }
    
  2. 合理拆分Hook

    // 推荐:每个Hook负责单一功能
    function useUser() { /* 用户相关逻辑 */ }