理解React的setState方法:数组状态新增元素的语法疑问
核心结论
你疑惑的语法可以拆成两部分区分归属:
...productList(展开运算符)是 JavaScript ES6+ 原生语法能力,和React无关setProductList是ReactuseStateHook 提供的状态更新方法,属于React内置特性
实现逻辑拆解
React的引用类型状态(数组、对象)要求必须传入全新的引用值才会触发重新渲染,不能直接修改原状态的值,你提到的写法就是为了符合这个规则设计的:
- 首先通过
...productList把原有productList数组的所有元素逐个展开,拷贝到新创建的数组中 - 再把新增的棒球对象作为最后一个元素,追加到这个新数组的末尾
- 最终将这个完整的新数组传给
setProductList,React会用新数组直接覆盖旧的productList状态,完成更新
你之前的误解是没注意到展开运算符的存在:如果没有
...的话,setProductList([productList, obj])生成的会是第一个元素为原数组、第二个元素为新对象的二维数组,完全不符合需求。你可以通过下面的代码对比差异:
// 正确写法(现有代码):生成追加了新元素的一维数组 setProductList([ ...productList, { item: "baseball", price: 4, description: "baseball desc" } ]) // 结果:[ {basketball}, {football}, {baseball} ] // 错误写法(无展开运算符):生成不符合预期的二维数组 setProductList([ productList, { item: "baseball", price: 4, description: "baseball desc" } ]) // 结果:[ [ {basketball}, {football} ], {baseball} ]
为什么不用push方法直接修改原数组?
如果用productList.push(新对象)再调用setProductList(productList),因为修改的是原数组本身,数组的引用地址没有变化,React会判定状态没有更新,不会触发组件重渲染,视图不会同步变化,所以必须创建新数组传入更新函数。
内容的提问来源于stack exchange,提问作者Eric Nguyen
相关产品推荐
相关产品推荐

