React中setState执行疑问:为何useEffect内重复触发?
React 18.2.0 中 setState 执行逻辑差异分析
一、useEffect 场景多输出一次 state:1 的原因
核心是React 18 开发环境严格模式的双重执行机制:
- 开发环境下,Strict Mode 会重复执行组件的渲染函数、useEffect 回调,用来检测未清理的副作用(比如残留的定时器、订阅)。
- 你的示例执行流程:
- 初始渲染:state=0,打印
state: 0→ 执行 useEffect,调用setState(1)触发更新。 - 第一次更新渲染:state=1,打印
state: 1→ 执行 useEffect,调用setState(1)(此时 state 已是1,正常不会触发更新,但 Strict Mode 强制再走一次更新流程)。 - 第二次更新渲染:再次打印
state: 1,这就是额外的输出。
- 初始渲染:state=0,打印
- 若关闭 Strict Mode(移除
<StrictMode>包裹),输出会和预期一致。
二、滚动事件回调场景符合预期的原因
滚动事件属于原生浏览器事件,和 React 控制的生命周期逻辑完全隔离:
- Strict Mode 不会对原生事件回调进行双重执行,只有 React 自身的渲染、副作用函数才会被重复执行。
- 当你在滚动回调中调用
setState(1),如果当前 state 已经是1,React 不会触发任何更新,自然不会产生额外的渲染和打印。
内容的提问来源于stack exchange,提问作者이명주
相关产品推荐
相关产品推荐

