React中useEffect多元素依赖数组的触发规则疑问
useEffect多依赖项的运行规则解答
多依赖的触发是「与」还是「或」逻辑
- 首先要明确:依赖数组的触发逻辑既不是
one && two的“与”判断,也不存在“变量满足某个特定值才触发”的规则,核心判断逻辑是组件每次重渲染后,会用Object.is逐位对比依赖数组每一项和上一次渲染时的值,只要任意一项的值/引用发生变化,就会执行effect回调,本质是“或”触发逻辑,但判断的维度是「值有没有变」,不是「值是不是满足某个条件」。 - 拿你给的示例代码
useEffect(()=>{alert("hi");},[one,two]);举实际场景:- 组件首次挂载完成时,一定会执行一次alert,这是useEffect的固有行为,和依赖的具体值无关
- 后续重渲染时,只要
one和上一次的值不一样,哪怕two完全没改动,也会触发alert - 反过来只要
two的值变了、one没动,一样会触发alert
- 如果你要实现“one和two同时满足某个条件才执行逻辑”的效果,别靠依赖数组控制,把条件判断写在effect回调内部就可以。
能不能在依赖数组里直接写比较表达式
- 语法层面这么写不会报错,代码能正常跑,但极度不推荐这种写法,非常容易写出预期外的bug。
- 本质原因是:依赖数组存的是每个位置表达式的最终计算结果,不是表达式逻辑本身。比如你写
[one===true,two===false],数组里实际存的就是两个布尔值,要么是true要么是false。 - 这种写法的隐蔽坑很多:比如当
one已经是true的时候,后续你把one从true改成另一个真值、甚至只是重新给one赋了一次true,one===true的计算结果始终是true,和上一次的值没有差异,effect就不会触发。这时候如果你的effect回调里还用到了one的其他属性,就会拿到陈旧的闭包值,出了问题很难排查。 - 符合官方规范的写法永远是:依赖数组里只放effect回调中直接用到的响应式值(state、props、组件内派生的响应式变量等),所有条件判断全部写到effect回调内部,参考示例:
useEffect(() => { // 所有业务条件判断放在回调内部实现 if (one === true && two === false) { alert("hi") } }, [one, two]); // 依赖项只列回调里实际用到的响应式值
内容的提问来源于stack exchange,提问作者Germán
相关产品推荐
相关产品推荐

