真实面经题目 · 原创解析
React Hooks 能用在 for 循环中么?为什么?条件语句呢?为什么?
这题考察 React Hooks 的调用顺序规则。Hooks 不能放在循环、条件和嵌套函数里,因为 React 依赖稳定调用顺序匹配内部状态槽位。
真实面经题目 · 原创解析
这题考察 React Hooks 的调用顺序规则。Hooks 不能放在循环、条件和嵌套函数里,因为 React 依赖稳定调用顺序匹配内部状态槽位。
Hooks 不能放在 for 循环、if 条件或嵌套函数中,必须在函数组件或自定义 Hook 的顶层调用。原因是 React 在每次 render 时按 Hook 调用顺序依次读取内部状态槽位:第一次 useState 对应第一个槽位,第二次 useEffect 对应第二个槽位。如果某次渲染因为条件或循环次数变化少调用、 多调用或换顺序,后面的状态和 effect 就会错位。正确做法是把条件放进 Hook 内部,例如 useEffect(() => { if (!enabled) return; ... }, [enabled]),或者把不同分支拆成子组件,让每个组件自己的 Hook 顺序稳定。
Hooks 只能在 React 函数组件或自定义 Hook 的顶层调用。不能放在 if、for、while、switch、try/catch、普通回调和嵌套函数里。
React 不靠变量名识别 Hook,而是按调用顺序记录链表或数组式的状态槽位。每次渲染的调用顺序一致,才能把这次的第 N 个 Hook 对上上次的第 N 个状态。
第一次渲染 enabled 为 true 调用了某个 useState,第二次 enabled 为 false 跳过它,后面的 useState/useEffect 就会读到错误槽位,状态和副作用都可能串位。
循环次数来自 props、state 或数据长度时,每次 render 调用 Hook 的次数可能不同。即便当前长度稳定,也容易在后续需求变化时破坏规则。
需要条件请求、条件订阅、条件计算时,保持 Hook 本身无条件调用,在回调内部判断并提前 return。这样调用顺序稳定,业务逻辑仍然可以有条件执行。
如果两个分支需要完全不同的一组 Hooks,可以把分支拆成不同子组件,由父组件条件渲染;每个子组件内部的 Hook 顺序仍然稳定。重复逻辑则抽成自定义 Hook。
顶层始终调用 useEffect,在 effect 回调里判断 if (!enabled) return;依赖数组包含 enabled 和请求参数。
不能在普通 map 回调里调用 Hook。可以把每一项渲染成子组件,在子组件顶层调用 Hook。
可以,但自定义 Hook 自身也要遵守同样规则:在顶层调用,不放进条件、循环或嵌套函数里。
如果早 return 出现在所有 Hook 调用之前,并且某些渲染走到后面调用了 Hook,就会造成不同渲染调用数量不一致。通常应把 Hook 放在早 return 之前,或拆组件。