React 靠「调用顺序」匹配 Hook 与状态:函数组件每次渲染时,useState、useEffect 按调用次序依次对应到 Fiber 节点上 memoizedState 链表的槽位。如果某次渲染因条件分支少调了一个 Hook,后续所有 Hook 的槽位都会错位,状态会串到错误的 Hook 上,产生隐蔽 bug。
因此规则是:只在顶层调用、只在函数组件或自定义 Hook 中调用。例外是 React 19 的 use(),被设计为可条件调用。易错点:提前 return 之后再写 Hook 同样违规;自定义 Hook 内部也必须遵守规则;eslint-plugin-react-hooks 的 rules-of-hooks 可静态拦截。追问:为什么不能把状态存闭包或 this、memoizedState 链表在 mount 与 update 阶段的差异。
// 错误:if (flag) useState(0)
// 正确:const [v, setV] = useState(0); if (!flag) return null