当状态是对象数组时更新 React 状态

新手上路,请多包涵

我有一组处于状态的对象:

 this.state = {
  items: [
    {id: 1, someattr: "a string", anotherattr: ""},
    {id: 2, someattr: "another string", anotherattr: ""},
    {id: 3, someattr: "a string", anotherattr: ""},
  ]
}

我需要能够根据 id 属性搜索 items 数组,然后更新 objects 属性。

我可以使用 id 参数在数组上通过 filteringfinding 获取对象。

然后我遇到的问题是更新数组,然后更新状态而不发生突变。

 //make sure we're not mutating state directly by using object assign
const items = Object.assign({}, this.state.items);
const match = items.find((item) => item.id === id);

此时我有一个匹配的对象,可以使用对象扩展更新它的属性:

 const matchUpdated = { ...match, someattr: 'a new value'};

我的问题是如何使用 matchUpdated 更新状态,以便覆盖初始查找操作返回的对象?

原文由 Mike Rifgin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 470
2 个回答

您的更新功能看起来像这样

updateItem(id, itemAttributes) {
  var index = this.state.items.findIndex(x=> x.id === id);
  if (index === -1)
    // handle error
  else
    this.setState({
      items: [
         ...this.state.items.slice(0,index),
         Object.assign({}, this.state.items[index], itemAttributes),
         ...this.state.items.slice(index+1)
      ]
    });
}

你像这样使用它

this.updateItem(2, {someattr: 'a new value'});

恶心吧?


如果你继续以这种方式构建一个复杂的应用程序,你通常会很头疼。我建议您研究一下 redux 或其他更适合解决这些问题的 Flux 实现。

Redux 使用状态缩减器的概念,每个缩减器都在应用程序状态的特定切片上工作。这样一来,您就不必在每次想要影响深度更改时手动挖掘整个状态。

Redux 的创建者 Dan Abramov 在网上免费提供了两个视频课程。 Dan 是一位优秀的老师,我只花了一个下午就对 Redux 模式感到满意。

原文由 Mulan 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果你想使用一个函数,我会这样做。函数参数是项目的 ID、您希望更改的属性以及该属性的新值。

 const [array, setArray] = useState([{
    id: 1,
    value: "aws",
    othervalue: "was"
  },
  {
    id: 2,
    value: "goo",
    othervalue: "nano"
  },
  {
    id: 3,
    value: "micro",
    othervalue: "marcro"
  },
])

const updateItem = (id, whichvalue, newvalue) => {
  let index = array.findIndex(x => x.id === id);
  /* This line is only necessary if your element's ID
     isn't its position/index in the array or related to it.
     In the case that it is, use the ID as the index, or run the function
     (binary/hash) that relates the ID to that position/index to find the
     index.
  */
  if (index !== -1) {
    let temporaryarray = array.slice();
    temporaryarray[index][whichvalue] = newvalue;
    setArray(temporaryarray);
  } else {
    console.log('no match');
  }
}

/* longer version:
var index = array.findIndex(x => x.id === id);
let g = array[index]
g[whichvalue] = newvalue

if (index === -1) {
  console.log('no match')
} else {
  setArray(
    [
      ...array.slice(0, index),
      g,
      ...array.slice(index + 1)
    ]
  );
}
*/

// how to use the function:
onPress = {
  () => updateItem(2, 'value', 'John Lemon')
}

原文由 Zentannen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进