React组件状态值未变更时为何仍触发重复渲染?
React useState 渲染次数疑问
案例一:设置与当前state相同的值,组件仅初始渲染
import { useState } from 'react'; import './App.css'; function App() { const [count, setCount] = useState(1) const handler = () => { setCount(1) } return ( <div> {console.log("rendering")} <p>{count}</p> <button onClick={handler}>click</button> </div> ); } export default App;
点击按钮三次后,浏览器控制台仅输出:
rendering
原因是每次点击调用setCount(1)时,新值与当前state完全一致,React直接跳过渲染流程,不会重新执行组件函数。
案例二:先修改state再设置相同值,出现额外渲染
import { useState } from 'react'; import './App.css'; function App() { const [count, setCount] = useState(1) const handler = () => { setCount(2) } return ( <div> {console.log("rendering")} <p>{count}</p> <button onClick={handler}>click</button> </div> ); } export default App;
按逻辑:初始渲染1次,第一次点击修改state为2触发第2次渲染,之后点击setCount(2)因state值未变,不应触发渲染。但实际点击三次按钮后,控制台输出三次rendering,总渲染次数为3次。
原因解释
React的更新流程分为「调度更新」和「渲染对比」两步,核心差异在于React对不同场景下相同值更新的判断逻辑:
- 案例一的逻辑:初始state就是1,每次点击调用
setCount(1)时,React能直接判定新值与当前state完全一致,且组件没有其他依赖变化,所以直接跳过整个渲染流程(包括组件函数执行),因此只有初始的1次输出。 - 案例二的逻辑:
- 初始渲染:执行组件函数,输出第1次
rendering - 第一次点击:
setCount(2)改变state值,触发完整渲染流程,输出第2次rendering并更新真实DOM - 第二次点击:此时state已经是2,调用
setCount(2)时,React无法在调度阶段直接确定组件函数生成的虚拟DOM是否会变化(即使state值相同,组件内可能存在其他动态逻辑),因此会先执行组件函数(输出第3次rendering),之后对比新旧虚拟DOM,发现无差异后跳过真实DOM更新 - 第三次点击:React已经缓存了前一次的判断结果,知道
setCount(2)不会带来任何变化,因此跳过渲染流程,不再输出rendering
- 初始渲染:执行组件函数,输出第1次
最终点击三次按钮后,控制台总共输出三次rendering。
内容的提问来源于stack exchange,提问作者noob_developer
相关产品推荐
相关产品推荐

