React Hooks 的优势和使用场景

45 阅读2分钟
# React Hooks 的优势和使用场景

## 核心优势

### 1. 简化组件逻辑
```javascript
// 类组件
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Increment
        </button>
      </div>
    );
  }
}

// 函数组件 + Hooks
function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
        </button>
    </div>
  );
}
  • 消除类组件的样板代码
  • 逻辑更集中,便于维护
  • 减少this绑定问题

2. 更好的逻辑复用

// 自定义Hook
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

// 在多个组件中使用
function ComponentA() {
  const width = useWindowWidth();
  // ...
}

function ComponentB() {
  const width = useWindowWidth();
  // ...
}
  • 替代高阶组件和render props
  • 自定义Hook可跨组件复用
  • 逻辑与UI解耦

3. 更细粒度的状态管理

function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [age, setAge] = useState(0);
  
  // 可以独立更新每个状态
  // 不需要合并state对象
}
  • 避免合并state对象
  • 状态更新更精确
  • 减少不必要的重新渲染

主要使用场景

1. 状态管理

const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
  • 适合管理局部组件状态
  • 简单状态优于复杂状态对象
  • 配合useReducer处理复杂状态

2. 副作用处理

useEffect(() => {
  // 数据获取
  const fetchData = async () => {
    try {
      setLoading(true);
      const res = await fetch('/api/data');
      setData(await res.json());
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  fetchData();
}, []); // 依赖数组控制执行时机
  • 数据获取
  • 订阅/取消订阅
  • DOM操作
  • 定时器管理

3. 性能优化

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);
  • 避免不必要的计算
  • 防止子组件不必要渲染
  • 优化高频更新场景

4. 上下文访问

const theme = useContext(ThemeContext);
const user = useContext(UserContext);
  • 简化context使用
  • 避免props层层传递
  • 多context组合使用

最佳实践

  1. 遵循Hook规则

    • 只在顶层调用Hook
    • 只在React函数中调用Hook
  2. 合理拆分Hook

    // 不好的做法 - 混合逻辑
    function useUserData() {
      const [user, setUser] = useState(null);
      const [posts, setPosts] = useState([]);
      // ...
    }
    
    // 好的做法 - 单一职责
    function useUser() {
      const [user, setUser] = useState(null);
      // ...
    }
    
    function useUserPosts(userId) {
      const [posts, setPosts] = useState([]);
      // ...
    }
    
  3. 优化依赖数组

    • 确保包含所有依赖项
    • 避免频繁变化的依赖
    • 使用useCallback/useMemo稳定引用
  4. 自定义Hook封装

    • use前缀命名