为什么设置相同state值时React仍会触发组件二次渲染?
为什么设置相同state仍会触发React组件重渲染
这个现象和React的版本、state更新逻辑直接相关:
- 你当前代码里
data定义在组件外部,是固定引用的对象,所以不存在「每次调用setFoo传入新对象导致引用不等」的问题。 - 补充提醒:如果把
data定义在组件内部,每次组件渲染都会生成新的对象引用,就算对象内容完全一致,React用来对比state的Object.is也会判定为不等,必然触发重渲染,这种情况需要用useMemo缓存对象或者用函数式更新来优化。
原因1:React 17及更早版本的机制问题
在React 17以及更低版本中,就算你传入setState的新值和当前state通过Object.is判断完全相等,React还是会执行一次当前组件的函数体,但会跳过后续的虚拟DOM对比和DOM更新操作。所以你能看到console.log('Rendered')被执行,但页面DOM不会有任何变化,不属于完整的重渲染流程。
这个问题在React 18已经被优化:只要新旧state判定相等,React会直接跳过整个重渲染流程,连组件函数都不会执行。
原因2:开发环境严格模式的额外执行
如果你的项目开启了React严格模式(根组件包裹了<React.StrictMode>),在开发环境下React会故意重复执行组件函数、Effect等逻辑,用来排查代码里隐藏的副作用问题,也会导致你看到额外的Rendered打印,这种情况生产环境会自动消失。
解决方案
如果要完全避免多余的执行,可以在更新前主动加一层判断:
<button onClick={() => { if (foo !== data) { setFoo(data) } }}>设置数据</button>
内容的提问来源于stack exchange,提问作者Mohamad Shiralizadeh
相关产品推荐
相关产品推荐

