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

React useState存储JSON对象时静态字段更新后回退问题求助

问题分析与修复

核心错误原因

你的代码存在两个关键问题,直接引发了name字段回退的异常:

  1. Array.push()返回值误用:push方法返回的是数组更新后的长度(数字),而非更新后的数组。你把new_phones赋值给phones字段时,实际是把数字塞给了原本该存数组的字段,直接破坏了state结构。
  2. 直接修改原State(突变):person.phones.push()直接修改了useState存储的原数组,违反了React state不可变的规则。React依赖state的引用变化触发重新渲染,直接修改原state会让React无法正确识别状态更新,进而出现渲染异常(比如其他字段回退到初始值)。

正确的更新写法

必须遵循state不可变原则,创建新的数组和对象来更新state:

// 先创建原数组的副本,再添加新元素
const newPhones = [...person.phones, {number: "new number", type: "Cell"}];
// 基于当前state创建新对象,替换phones字段
setPerson({...person, phones: newPhones});

更推荐用函数式更新,避免闭包导致的state过时问题:

setPerson(prevPerson => ({
  ...prevPerson,
  phones: [...prevPerson.phones, {number: "new number", type: "Cell"}]
}));

原写法导致name回退的本质原因

当你直接修改person.phones后,原state对象的引用并没有改变(只是修改了它的属性,对象本身还是同一个)。后续调用setPerson({...person, phones: new_phones})时,若person是闭包中捕获的旧值(比如初始state),就会把旧的name值重新覆盖回去,导致页面显示回退。而函数式更新通过prevPerson获取最新的state,就能避免这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:08:19