React Hooks 的优势和使用场景

32 阅读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'); }
  • 替代高阶组件模式
    传统高阶组件容易产生"wrapper hell",使用Hook可扁平化组件结构:
    // 替代withRouter等高阶组件
    function MyComponent() {
      const navigate = useNavigate();
      // 直接使用路由方法
    }
    

2. 逻辑关注点分离

  • 副作用管理精细化
    function UserProfile({ userId }) {
      // 用户数据获取
      const [user, setUser] = useState(null);
      useEffect(() => {
        fetchUser(userId).then(setUser);
      }, [userId]);
    
      // 在线状态监听
      const [isOnline, setIsOnline] = useState(false);
      useEffect(() => {
        const sub = subscribeToOnlineStatus(userId, setIsOnline);
        return () => sub.unsubscribe();
      }, [userId]);
    }
    
    相比class组件的生命周期方法,相关逻辑可以更集中组织。

3. 性能优化手段

  • 记忆化计算

    const expensiveValue = useMemo(() => {
      return computeExpensiveValue(a, b);
    }, [a, b]);
    
    const handleClick = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    
  • 精准依赖控制

    useEffect(() => {
      // 仅在userId变化时执行
    }, [userId]); 
    

4. 使用场景详解

状态管理

// 表单状态管理
function Form() {
  const [form, setForm] = useState({ name: '', age: 0 });
  const handleChange = useCallback((e) => {
    setForm(prev => ({ ...prev, [e.name]: e.value }));
  }, []);
}

副作用处理

// 定时器管理
function Timer() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const timer = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    return () => clearInterval(timer);
  }, []);
}

上下文访问

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

5. 最佳实践

  1. Hook调用规则

    • 只在顶层调用Hook
    • 只在React函数中调用
  2. 自定义Hook规范

    • 命名必须使用use前缀
    • 可以返回任意值(包括JSX)
  3. 性能优化策略

    // 依赖项数组正确处理
    useEffect(() => {
      // effect逻辑
    }, [dep1, dep2]); // 明确声明所有依赖
    
    // 必要时使用ref保存可变值
    const intervalRef = useRef();
    useEffect(() => {
      intervalRef.current = setInterval(...);
      return () => clearInterval(intervalRef.current);
    }, []);
    

6. 注意事项

  • 闭包陷阱

    // 错误示例
    useEffect(() => {
      const timer = setInterval(() => {
        console.log(count); // 总是初始值
      }, 1000);
      return () => clearInterval(timer);
    }, []);
    
    // 正确写法
    useEffect(() => {
      const timer = setInterval(() => {
        console.log(count); 
      }, 1000);
      return () => clearInterval(timer);
    }, [count]); // 添加依赖
    
  • 无限循环

    // 错误的依赖设置会导致无限循环
    useEffect(() => {
      setCount(count + 1); // 每次渲染都修改count
    }, [count]); // count变化又触发effect
    

7. 生态整合

  • **状态管理库