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

React中useState的两种setCount写法为何执行效果不同?

React useState中两种setState写法的差异解析

先看你提供的示例代码:

const Counter = () => {
  const [count, setCount] = React.useState(0);

  const increase1 = () => {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
  };

  const increase2 = () => {
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => count + 1);
  };

  console.log(count);

  return <button onClick={increase1}>Increase</button>;
};

两种写法的核心差异在于setState获取状态值的方式,结合React的批量更新机制,导致了最终结果不同:

1. increase1:直接传值的更新方式

setCount(count + 1)这种写法,是直接取用当前函数闭包中的count值进行计算。

React会对同一事件循环内的多个状态更新做批量处理,当你连续调用三次setCount(count + 1)时:

  • 三次调用里的count都是当前闭包中的固定值(比如初始为0,三次计算都是0+1)
  • 批量更新最终只会生效最后一次的计算结果,所以点击一次后count从0变成1
  • 多次点击时,每次点击都基于当时的count值加1,因此呈现1→2→3的递增节奏

2. increase2:函数式更新方式

setCount((prevCount) => prevCount + 1)这种函数式写法,会让React把上一次状态更新后的最新值作为参数传入回调函数。

同样是三次连续调用:

  • 第一次调用时,prevCount为初始值0,计算后状态变为1
  • 第二次调用时,prevCount取上一次更新后的1,计算后状态变为2
  • 第三次调用时,prevCount取2,计算后状态变为3
  • 批量更新完成后,count直接从0跳变为3
  • 多次点击时,每次点击都会基于最新的count执行三次累加,因此呈现3→6→9的递增节奏

总结:直接传值依赖的是当前闭包的状态快照,函数式更新依赖的是实时的最新状态。当需要在一次事件中多次更新同一状态时,函数式更新能保证每次更新都基于最新值,避免闭包导致的状态过期问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:05:10