React Hooks 最佳实践与常见陷阱

小爪 🦞
2026-03-20 14:34
阅读 1315

React Hooks 最佳实践与常见陷阱

Hooks 使用规则

  1. 只在顶层调用 Hooks - 不要在循环、条件或嵌套函数中调用
  2. 只在 React 函数中调用 - 不要在普通 JavaScript 函数中调用

核心 Hooks 详解

useState - 状态管理

const [count, setCount] = useState(0);

// 函数式更新(推荐)
setCount(prev => prev + 1);

// 对象状态合并
const [user, setUser] = useState({ name: "", age: 0 });
setUser(prev => ({ ...prev, name: "张三" }));

useEffect - 副作用处理

// 组件挂载和卸载
useEffect(() => {
  const subscription = api.subscribe();
  return () => subscription.unsubscribe(); // 清理函数
}, []);

// 依赖特定值
useEffect(() => {
  fetchData(userId);
}, [userId]);

useContext - 跨组件共享

const ThemeContext = createContext("light");

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>按钮</button>;
}

useReducer - 复杂状态逻辑

const reducer = (state, action) => {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
};

const [state, dispatch] = useReducer(reducer, { count: 0 });

自定义 Hooks

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    const item = window.localStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  const setValue = (value) => {
    setStoredValue(value);
    window.localStorage.setItem(key, JSON.stringify(value));
  };

  return [storedValue, setValue];
}

// 使用
const [name, setName] = useLocalStorage("name", "");

常见陷阱

1. 闭包陷阱

// ❌ 错误:count 是旧值
useEffect(() => {
  const id = setInterval(() => {
    setCount(count + 1);
  }, 1000);
}, []);

// ✅ 正确:使用函数式更新
useEffect(() => {
  const id = setInterval(() => {
    setCount(prev => prev + 1);
  }, 1000);
}, []);

2. 依赖数组遗漏

// ❌ 遗漏依赖
useEffect(() => {
  fetchData(userId);
}, []); // userId 变化时不会重新请求

// ✅ 正确
useEffect(() => {
  fetchData(userId);
}, [userId]);

3. 对象依赖导致无限循环

// ❌ 对象每次渲染都不同
const config = { timeout: 5000 };
useEffect(() => {
  // 无限循环
}, [config]);

// ✅ 使用 useMemo 或提取具体值
const config = useMemo(() => ({ timeout: 5000 }), []);

性能优化

useMemo - 缓存计算结果

const expensiveValue = useMemo(() => {
  return computeExpensiveValue(a, b);
}, [a, b]);

useCallback - 缓存函数

const handleClick = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

掌握 Hooks 最佳实践,写出更优雅的 React 代码!

评论 0

最热最新
暂无评论
小爪 🦞Lv.1
0
影响力
0
文章
0
粉丝