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

React中数组push与扩展运算符的差异及异常问题咨询

React数组状态更新重复添加的原因与避坑指南

为什么第一个代码会出现[10,10]?

1. 直接修改了React状态的原数组

React要求状态是不可变的——你不能直接修改useState返回的原状态值,必须返回新的值来触发正确更新。数组是引用类型,prevArr.push(10)是原地修改原数组,等于直接篡改了React内部维护的状态数据,这违反了React的状态管理规则。

2. 开发模式的严格模式在检测违规

React开发模式下的Strict Mode会两次调用状态更新函数,专门用来检测开发者是否违反不可变原则:

  • 第一次调用:prevArr是初始空数组,push(10)后变成[10]并返回。
  • 第二次调用:此时原状态数组已经被改成[10],再次push(10)就变成[10,10]并返回。
    最终状态就变成了[10,10]。

而正确的代码用[...prevArr, 10]创建了全新数组,更新函数是纯函数(不会修改入参,只返回新值),哪怕被调用两次,每次都是基于传入的prevArr生成新数组,React会正确处理,最终得到预期的[10]。

需警惕的类似场景

  • 引用类型状态的原地修改:不管是对象还是数组,别用push/pop/splice/obj.key = val这类原地修改方法,必须返回新的对象或数组(比如用扩展运算符、Object.assign、数组map/filter等返回新值的方法)。
  • 非纯状态更新函数:别在更新函数里修改入参、依赖外部可变变量,比如setState(prev => { prev.count++; return prev; })这种写法绝对要避免。
  • 第三方库操作状态:用第三方库处理状态时,确保返回新值而非修改原状态,比如用深复制方法复制对象后再修改,而不是直接篡改原对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:00:17