You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React useState重复设置相同状态值时的重渲染机制疑问

React状态更新疑惑:重复设置相同值为何触发第二次重渲染?

我用一个简单计算器示例验证React state的工作机制,初始值设为1:

  • 第一次点击+按钮,控制台输出“Run”,计算器显示“2”;
  • 第二次点击+按钮,控制台仍输出“Run”和“2”,计算器还是显示“2”;
  • 继续点击+按钮,控制台无任何输出。

对应的代码如下:

import {useState} from "react";

const App = () => {

    console.log("Run")

    const [counter, setCounter] = useState(1);

    console.log(counter)

    const addHandler = () => {
        setCounter(2);
    };
    const subtractHandler = () => {
        setCounter(counter - 1);
    };
    return <div className="app">
        <h1>{counter}</h1>
        <button onClick={addHandler}>+</button>
        <button onClick={subtractHandler}>-</button>
    </div>
  };

export default App;

我的疑惑是:第一次点击后counter已经是2了,第二次点击+按钮再次设置counter为2时,为什么控制台还会输出“Run”和“2”?按我的理解,状态变量变更才会触发组件重渲染啊。


核心原因:React的状态更新批处理与重渲染优化时机

这其实是React的状态更新批处理和重渲染优化延迟性导致的:

  1. 第一次点击后的状态与闭包
    第一次点击+按钮时,addHandler里的setCounter(2)触发状态更新,组件重渲染,此时counter变为2,同时生成了新的addHandler闭包(这个闭包绑定的counter值是2)。

  2. 第二次点击的更新逻辑
    第二次点击+按钮时,调用的是新生成的addHandler,执行setCounter(2)。在同步更新场景(比如点击事件触发的更新)下,React不会在调用setState时立刻判断新值是否与当前状态相等,而是会先将更新加入队列并触发一次重渲染,之后才会启用“相同值不触发重渲染”的优化逻辑。

  3. 后续点击的优化生效
    第二次重渲染完成后,新的addHandler闭包绑定的counter还是2。第三次点击+按钮时,React已经完成了前一次的状态对比校验,此时再调用setCounter(2),会直接跳过状态更新和重渲染,所以控制台没有输出。

简单总结:React的“相同状态值不触发重渲染”优化,在连续的同步更新中不会立刻生效,需要经过一次重渲染后,后续的相同值更新才会被拦截。

内容的提问来源于stack exchange,提问作者Tobin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:15:39