React Hooks 的优势和使用场景

8 阅读1分钟
# React Hooks 的优势和使用场景

## 核心优势

### 1. 简化组件逻辑
- **代码更简洁**:消除类组件的样板代码(constructor、this绑定等)
- **逻辑复用**:通过自定义Hook实现跨组件逻辑复用
- **关注点分离**:将相关逻辑聚合到独立Hook中

```jsx
// 传统class组件
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return <button onClick={this.handleClick}>{this.state.count}</button>;
  }
}

// 使用Hook的函数组件
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

2. 更好的状态管理

  • 细粒度控制useState替代单一state对象
  • 派生状态useMemo优化计算开销
  • 复杂状态useReducer处理多状态关联
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(false);
  
  useEffect(() => {
    setLoading(true);
    fetchUser(userId).then(data => {
      setUser(data);
      setLoading(false);
    });
  }, [userId]);

  const age = useMemo(() => {
    return user ? new Date().getFullYear() - user.birthYear : null;
  }, [user]);

  if (loading) return <Spinner />;
  return <Profile user={user} age={age} />;
}

3. 生命周期整合

  • 副作用管理useEffect统一处理componentDidMount/Update/Unmount
  • 布局测量useLayoutEffect处理DOM变更后的同步操作
  • 资源清理:返回清理函数避免内存泄漏
function WindowSize() {
  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 <div>Window size: {size.width}x{size.height}</div>;
}

主要使用场景

1. 状态逻辑复用

  • 自定义Hook封装:如useFetchuseLocalStorage
  • 替代HOC/Render Props:减少组件嵌套层级
function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const stored = localStorage.getItem(key);
    return stored !== null ? JSON.parse(stored) : initialValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
}

function ThemeToggle() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');
  const toggle = () => setTheme(t => t === 'light' ? 'dark' : 'light');
  
  return <button onClick={toggle}>Current: {theme}</button>;
}

2. 副作用管理

  • 数据获取:结合useEffectAbortController
  • 事件订阅:WebSocket、键盘事件等
  • 动画控制:配合requestAnimationFrame
function useAnimation(callback) {
  const frameRef = useRef();
  
  const animate = useCallback(() => {
    callback();
    frameRef.current = requestAnimationFrame(animate);
  }, [callback]);

  useEffect(() => {
    frameRef.current = requestAnimationFrame(animate);
    return () => cancelAnimationFrame(frameRef.current);
  }, [animate]);
}

function MovingBox() {
  const [position, setPosition] = useState(0);
  useAnimation(() => setPosition(p => (p + 1) % 100));
  return <div style={{ transform: `translateX(${position}px)` }} />;
}

3. 性能优化

  • 记忆化计算useMemo避免重复计算
  • 回调记忆