症状
组件抛出 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 调用序列恒定。