将状态更新为嵌套对象

时间:2018-08-22 20:42:41

标签: javascript reactjs

我的应用中有这种状态

state = {
  abc: true,
  array: [
    { id: 12345, done: false },
    { id: 10203, done: false },
    { id: 54321, done: false }
  ]
}; 

我正在寻找以下问题的解决方案:当将类似handle(12345)的内容作为参数传递给处理函数时,我需要像以下函数中那样,将完成的属性相应地更改为传递的id:

  handle = id => {
  this.state.array.map(e => {
    if (e.key === id) {
      this.setState({array: [
        { id: id, done: true },
        { id: 10203, done: false },
        { id: 54321, done: false }
      ]})
    }
  });
};

简单来说,我只需要根据提供的ID更改数组中的一个对象即可。

感谢您的帮助或提示!

4 个答案:

答案 0 :(得分:4)

我将handle方法编写为:

handle = id => {
  this.setState(prevState => {
    const { array } = prevState;
    return {
      array: [
        ...array.filter(o => o.id !== id),
        {id, done: true}
      ]
    };
  });
};

这里的想法是,从旧状态中删除匹配的id,然后将具有arrayid属性的done添加为{{ 1}}。

答案 1 :(得分:3)

一旦允许您将state重组为哈希图而不是数组:

state = {
  abc: true,
  array: {
    12345: { done: false },
    10203: { done: false },
    54321: { done: false }
  ]
}; 

那么您将能够使用扩展算子的功能:

let id = 12345;
this.setState({
    array: {
        ...this.state.array,
        [id]: {
            ...this.state.array[id], 
            done: true
        }
    }
});

否则,使用array.map()似乎是唯一的选择

答案 2 :(得分:1)

您可以使用此Redux pattern返回一个新数组,其中相关元素已更改,同时保持数组不变:

handle = id => {
  const updatedArray = this.state.array.map(e => {
    if (e.key === id) {
      return { id: id, done: true };
    }
    else {
      return e;
    }
  });
  this.setState({array: updatedArray});
};

这使您的数据结构保持不变,而仅更改您需要更改的内容。

答案 3 :(得分:0)

var newArray = this.state.array;
  for(var i = 0; i < newArray.length; i++){
      if(newArray[i].id === 12345) {
        newArray[i].done = true;
      }
  }

  this.setState({array: newArray});

通过在此处创建newArray,您将避免直接触摸状态元素,因此可以在设置状态后更改其中想要的任何内容。