React Hooks 最佳实践

Hooks 基础原则

只在顶层调用

// 错误:在条件语句中调用
function Component({ show }) {
  if (show) {
    const [value, setValue] = useState(0); // 错误!
  }
}

// 正确:始终在顶层调用
function Component({ show }) {
  const [value, setValue] = useState(0);
  if (!show) return null;
  // ...
}

只在 React 函数中调用

不要在普通 JavaScript 函数中调用 Hooks。

常用 Hooks 最佳实践

useState

// 惰性初始化
const [state, setState] = useState(() => {
  // 只在首次渲染时执行
  return expensiveComputation();
});

// 函数式更新
setState(prev => prev + 1);

useEffect

// 正确声明依赖
useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]); // 不要遗漏依赖

// 清理副作用
useEffect(() => {
  const subscription = subscribe();
  return () => subscription.unsubscribe();
}, []);

useMemo 和 useCallback

// 缓存计算结果
const sortedItems = useMemo(() => {
  return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);

// 缓存回调函数
const handleClick = useCallback((id) => {
  setSelected(id);
}, []); // 如果依赖 setSelected,可能需要添加到依赖数组

自定义 Hooks

// 封装可复用逻辑
function useWindowSize() {
  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 size;
}

// 使用
function Component() {
  const { width, height } = useWindowSize();
  // ...
}

总结

遵循 Hooks 的使用规则,正确声明依赖,合理使用缓存,可以写出更简洁、更高效的 React 代码。