React中useEffect未传依赖数组时为何会反复执行?
useEffect 依赖传参差异导致执行逻辑不同的核心原因
先把 React 官方定义的 useEffect 执行规则说透,三种传参对应三种执行时机,没有什么特殊魔法:
- 不传第二个依赖参数:组件每一次渲染完成后,都会执行 effect 内部的逻辑
- 传入空数组
[]:仅在组件首次挂载、第一次渲染完成后执行一次 effect,后续任何重渲染都不会触发这个 effect 重跑 - 传入带具体值的数组
[dep1, dep2]:首次渲染执行后,后续每次重渲染会浅对比数组内所有值和上一次渲染的对应值,只要有任意一个值变化,就重跑 effect
不传依赖时无限迭代的原因
你写的无依赖版本里,effect 内部请求完成后会调用 setData 更新状态,状态更新会直接触发组件重渲染。
因为没传依赖数组,重渲染完成后会再次执行 effect,effect 里又跑请求、又调用 setData 触发重渲染,直接形成了「执行effect → 更新状态 → 重渲染 → 再执行effect」的死循环。
补充:哪怕 effect 里没有更新状态的逻辑,只要组件因为 props 变化、其他 state 更新触发了重渲染,无依赖的 effect 都会跟着每次重跑,不是只有死循环场景下才会重复执行。
传空数组仅执行一次的原因
空数组相当于给 React 传了个明确信号:这个 effect 不依赖组件内任何会变化的 state、props,后续不管组件怎么重渲染,都不需要重新执行。
所以它只会在组件第一次挂载到页面时跑一次,哪怕 effect 里调用了 setData 触发重渲染,React 检查到依赖数组是空的,没有需要对比的依赖项,就不会重复执行 effect,自然不会产生循环。
两种写法的核心代码对比
无依赖(会循环)写法:
useEffect(() => { axios .get('https://jsonplaceholder.typicode.com/users') .then((result) => setData(result.data)); console.log('t'); // 未传入第二个依赖参数 });
空依赖(仅执行一次)写法:
useEffect(() => { axios .get('https://jsonplaceholder.typicode.com/users') .then((result) => setData(result.data)); console.log(data); }, []); // 第二个参数传入空数组
小提醒:空数组的 effect 里如果用到了 state 或者 props,永远只能拿到初始的陈旧值,比如上面空依赖版本里的
console.log(data)第一次打印永远是 undefined,因为后续 data 更新不会触发 effect 重跑,拿不到最新值。
内容的提问来源于stack exchange,提问作者HelloWorld1
相关产品推荐
相关产品推荐

