首页 > 解决方案 > 使用 setState 跨对象数组更新对象

问题描述

我的问题与这个问题有关,但这里的问题是我必须传递对象属性并且我只想更新一个对象。如果我使用map它会更新我的对象数组中的所有对象。它的结构是:

[
    {
      id: 1,
      itemNames: ['aaa','xxx'],
      removed: [],
      ...
    },
    {
      id: 1,
      itemNames: ['yyy', 'xxx'],
      removed: [],
      ...
    },
    ...
]

我的逻辑是:我在 itemNames 中查找项目名称,如果它存在于状态中 - 从第一个对象出现中将其删除并将其添加到该对象的已删除属性中。我设法用地图来做到这一点,但是它对每个给定项目名称的对象都做到了。

function filterByItemName(itemName) {
  this.setState(prevState => ({
    ...prevState,
    arr: prevState.arr.map(item) => {
      if (item.itemNames.includes(itemName)) {
        return {
          ...item,
          removed: [...item.removed, itemName],
          itemNames: removeFirstFoundElement(item.itemNames, itemName),
        };
      }
      return item;
    }),
  }));
}

以下代码的工作方式是找到具有给定 itemName 的所有对象-但我只想更改第一种情况...调用后filterByItemName('xxx')我希望它是:

[
    {
      id: 1,
      itemNames: ['aaa'],
      removed: ['xxx],
      ...
    },
    {
      id: 1,
      itemNames: ['yyy', 'xxx'],
      removed: [],
      ...
    },
    ...
]

而现在是这样的:

[
    {
      id: 1,
      itemNames: ['aaa'],
      removed: ['xxx],
      ...
    },
    {
      id: 1,
      itemNames: ['yyy'],
      removed: ['xxx'],
      ...
    },
    ...
]

标签: javascriptarraysreactjs

解决方案


我认为您可以设置一个shouldInsert标志来检查您是否已经插入过一次。这是我的方法。如果你能codesandbox在这里分享一些链接会更容易。

function filterByItemName(itemName) {
  let shouldInsert = true;
  this.setState(prevState => ({
    ...prevState,
    arr: prevState.arr.map(item) => {
      const found = item.itemNames.includes(itemName);
      if (found && shouldInsert) {
        shouldInsert = false;
        return {
          ...item,
          removed: [...item.removed, itemName],
          itemNames: removeFirstFoundElement(item.itemNames, itemName),
        };
      }
      return item;
    }),
  }));
}

推荐阅读