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

React严格模式下副作用判定及useState更新翻倍问题咨询

核心原理说明

首先明确React严格模式在开发环境的运行规则:所有传入useState更新器、useMemo、useReducer的函数都会被重复调用两次,目的是主动暴露不符合纯函数要求的代码逻辑。

两个更新函数的本质差异

你遇到的差异核心是两个setXxx传入的更新函数,一个是有副作用的非纯函数,另一个是无副作用的纯函数:

  • 第一个更新函数() => increaseCount1():内部修改了模块全局作用域下的普通变量count,这个变量不属于React托管的状态,每次调用函数都会永久改变外部变量的值,这就是典型的副作用。
  • 第二个更新函数() => countState2 + 1:仅读取当前渲染周期闭包捕获的React托管状态countState2,没有修改任何外部变量,相同输入永远返回相同结果,属于纯函数。

具体执行过程拆解

Btn1点击后的执行流程:

  1. 触发点击事件,setCountState接收更新函数进入处理逻辑
  2. 严格模式第一次调用更新函数:执行++count,全局count从0变为1,返回值1
  3. 严格模式第二次调用更新函数:再次执行++count,全局count从1变为2,返回值2
  4. React最终将第二次调用的返回值2作为新状态赋值给countState,页面就显示为加了2的结果

Btn2点击后的执行流程:

  1. 触发点击事件,setCountState2接收更新函数进入处理逻辑
  2. 严格模式第一次调用更新函数:读取当前闭包内的countState2值(比如当前是0),返回0+1=1,没有修改任何外部变量
  3. 严格模式第二次调用更新函数:读取的还是当前闭包内未改变的countState2值0,还是返回0+1=1
  4. React最终将返回值1作为新状态赋值给countState2,符合预期

正确的编码规则

React要求所有传入状态更新器、计算缓存的函数必须是纯函数,满足两个要求:

  • 相同输入永远返回相同输出
  • 不修改任何函数外部的变量、不触发外部可观测的变化(比如修改全局变量、修改DOM、发起请求等都属于副作用)

如果要修改外部变量,请把逻辑放到状态更新函数之外,或者直接使用React托管的状态做更新,比如用setCountState(prev => prev + 1)的写法即可避免该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:30:02