微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React JS 从数组更新对象

如何解决React JS 从数组更新对象

我有一组处于反应状态的对象。

[
  {
    id: 'd8t4gf',title: 'Working on',items: [{ title: 'Item 1' },{ title: 'Item 2' },{ title: 'Item 3' }],},{
    id: '8jy8g',title: 'Done',{ title: 'Item 2' }],]

我正在尝试像这样更新第二个对象的项目。

const handleAddNewItemSubmit = (title,id) => {
  const listIndex = lists.findindex((list) => list.id === id);

  const newData = [...lists];

  newData[listIndex].items = [...newData[listIndex].items,{ title }];

  setLists(newData);
};

有没有更好的方法来做到这一点?

解决方法

您正在改变现有状态(特别是数组对象 - 例如 lists[0]),这在 React 中永远不应该完成。你正在做的事情可能碰巧奏效,但这不是一个好方法。

尝试类似这样的方法,将所有内容克隆到嵌套的 items 属性:

const handleAddNewItemSubmit = (title,id) => {
  setLists(
    lists.map(list => list.id !== id ? list : ({
      ...list,items: [...list.items,{ title }]
    })
  );
};
,
const handleAddNewItemSubmit = (title,id) => {
  const listIndex = lists.findIndex((list) => list.id === id);

  const newData = [...lists];

  newData[listIndex].items = [...newData[listIndex].items,{ title }];

  setLists(newData);
};

在上面的代码中,当你做 const newData = [...lists] 时,它只是做浅拷贝,即只有顶级引用会不同,但如果有任何嵌套对象,它们将具有与 {{} 相同的引用1}}。

因此,当您执行 lists 时,您实际上指的是同一个对象,即 newData[listIndex].items。由于 lists[listIndex].items 是一个数组,而它又是一个对象,因此它具有与 newData[listIndex].items 相同的引用。

所以,最终你会改变状态。为了避免这种情况,我们可以通过不同的方式进行状态更新

lists[listIndex].items

下面我模拟了两个例子,一个改变顶级对象,另一个在传播后改变嵌套对象。

const handleAddNewItemSubmit = (title,id) => {
  setLists(oldLists => oldLists.map(list =>
    list.id === id ? ({
      ...list,{ title }]
    }) : list))
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。