← 中文资源

简体中文版本

React: Hooks 只能在函数组件体内调用

修复 React 的 Hook 顺序错误:将 Hook 移出条件、循环与回调,并理解其强制的渲染顺序不变式。

阅读英文原文

症状

组件抛出 Hook 顺序错误,或 “Hooks can only be called inside the body of a function component”。它通常只在某个标志翻转时出现,因此切换状态即可复现。

诊断

阅读报错信息并找出被条件包裹的 Hook:

function Panel({ user }) {
  if (!user) return <p>Loading</p>; // early return BEFORE hooks
  const [open, setOpen] = useState(false); // order changes later
  useEffect(() => { /* ... */ }, []);
  return <div>{open}</div>;
}

当 user 为 null 与存在时,Hook 的数量不一致。

修复

把所有 Hook 提升到分支之上:

function Panel({ user }) {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    if (user) { /* conditional work inside the effect */ }
  }, [user]);

  if (!user) return <p>Loading</p>;
  return <div>{open}</div>;
}

验证

在 null 与有值之间切换 user;两种情况下组件都能渲染且无 Hook 顺序错误,证明 Hook 调用序列恒定。