React 更新 state 中的对象

更新一个嵌套对象

考虑下面这种结构的嵌套对象:

js 复制代码
const [person, setPerson] = useState({
  name: 'Niki de Saint Phalle',
  artwork: {
    title: 'Blue Nana',
    city: 'Hamburg',
    image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',
  }
});

但是在 React 中,你需要将 state 视为不可变的!为了修改 city 的值,你首先需要创建一个新的 artwork 对象(其中预先填充了上一个 artwork 对象中的数据),然后创建一个新的 person 对象,并使得其中的 artwork 属性指向新创建的 artwork 对象:

js 复制代码
const nextArtwork = { ...person.artwork, city: 'New Delhi' };
const nextPerson = { ...person, artwork: nextArtwork };
setPerson(nextPerson);

或者,写成一个函数调用:

js 复制代码
setPerson({
  ...person, // 复制其它字段的数据
  artwork: { // 替换 artwork 字段
    ...person.artwork, // 复制之前 person.artwork 中的数据
    city: 'New Delhi' // 但是将 city 的值替换为 New Delhi!
  }
});

这虽然看起来有点冗长,但对于很多情况都能有效地解决问题

下面是常见数组操作的参考表。当你操作 React state 中的数组时,你需要避免使用左列的方法,而首选右列的方法:

避免使用 (会改变原始数组) 推荐使用 (会返回一个新数组)
添加元素 push,unshift concat, ...arr 展开语法(例子)
删除元素 pop,shift,splice filter,slice(例子)
替换元素 splice,arri = ... 赋值 map(例子)
排序 reverse,sort 先将数组复制一份(例子)

你应该创建一个 新 数组,其包含了原始数组的所有元素 以及 一个在末尾的新元素。这可以通过很多种方法实现,最简单的一种就是使用 ... 数组展开 语法:

js 复制代码
setArtists( // 替换 state
  [ // 是通过传入一个新数组实现的
    ...artists, // 新数组包含原数组的所有元素
    { id: nextId++, name: name } // 并在末尾添加了一个新的元素
  ]
);

对象并不是 真的 位于数组"内部"。可能他们在代码中看起来像是在数组"内部",但其实数组中的每个对象都是这个数组"指向"的一个存储于其它位置的值。这就是当你在处理类似 list0 这样的嵌套字段时需要格外小心的原因。

当你更新一个嵌套的 state 时,你需要从想要更新的地方创建拷贝值,一直这样,直到顶层。

相关推荐
OpsEye18 分钟前
怎么实现大模型的按用户、按应用配额限流?
javascript·ai编程
云舜言传1 小时前
Bloom 手势演示操作 · 录屏指南
javascript·深度学习·机器学习
Highcharts.js4 小时前
BI可视化图表“维护难”问题的解决方案
开发语言·前端·javascript·编辑器·ecmascript·bi·highcharts
倚窗听花_5 小时前
IIS部署前端Vue项目
前端·javascript·vue.js
yixun_gdas5 小时前
政企网站错敏巡查:错敏都藏在哪些位置?
开发语言·前端·javascript·内容运营
小羊没烦恼!5 小时前
.NET 11 Runtime Async 详解
java·运维·开发语言·javascript·python
飞飞鱼在摸鱼6 小时前
前端转Agent开发 | JavaScript 从 0 到 1 完全指南
前端·javascript
Suprman6 小时前
从 B/S 到 Electron:平面排版套料系统桌面版开发实战
javascript·平面·electron·排序算法
u0111026756 小时前
Vue 3 统一右侧编辑面板:布局、滚动与底部操作区设计
javascript·vue.js·ecmascript
change_fate6 小时前
Vue 3 Composable 函数指南
前端·javascript·vue.js