繁体   English   中英

React-使用setState更新状态下的对象数组

[英]React - updating an object array in the state with setState

我正在开发一个餐桌策划应用,可以将客人分配到餐桌。 我已经创建了一个名为tabledata的对象数组,其中将包含如下对象:

  this.state = { tabledata: [ { name: "Top Table", guests: ["guest1", "guest2", "guest3"] }, { name: "Table One", guests: ["guest3", "guest4", "guest5"] } ] } 

然后,我要创建一个拖放界面,来宾可以在表之间移动。 我试图像这样更新状态:

  updateTableList (tablename, guest) { const selectedTableObj = this.state.tabledata.filter((tableObj) => tableObj.name === tablename); const otherTableObjs = this.state.tabledata.filter((tableObj) => tableObj.name !== tablename); selectedTableObj[0].guests.push(guest); const updatedObjectArray = [...otherTableObjs, selectedTableObj]; this.setState({ tabledata: [...otherTableObjs, ...selectedTableObj] }); } 

这行得通,但是因为我要从状态中删除selectedTableObj,然后将其添加到数组的末尾,所以我在屏幕上得到了一些时髦的结果。 更新的表始终位于页面底部(如您所愿)。

我如何更新对象而不更改其在数组中的位置?

使用Array.findIndex()查找要更新的表的索引。 创建一个新的tabledata阵列。 使用Array.slice()获取更新表之前和之后的项目,并将它们散布到新的tabledata数组中。 使用对象散布创建一个新的表对象,添加更新的guests数组,并在前面的各项之间添加表对象:

代码(未经测试):

updateTableList(tablename, guest) {
  this.setState((prevState) => {
    const tableData = prevState.tabledata;
    const selectedTableIndex = tableData.findIndex((tableObj) => tableObj.name === tablename);
    const updatedTable = tableData[selectedTableIndex];

    return {
      tabledata: [
        ...prevState.tabledata.slice(0, selectedTableIndex),
        {
          ...updatedTable,
          guests: [...updatedTable.guests, guest]
        },
        ...prevState.tabledata.slice(selectedTableIndex + 1)
      ]
    };
  });
}

selectedTableObj[0].guests.push(guest)直接改变了React中不鼓励使用的状态。

尝试这个:

this.setState((prevState) => {
  const newData = [...prevState.tabledata];
  // if you pass in `index` as argument instead of `tablename` then this will not be needed
  const index = prevState.tabledata.findIndex(table => tableObj.name === tablename); 

  newData[index] = {
    ...newData[index],
    guests: newData[index].guests.concat([guest]),
  };
  return { tabledata: newData };
});

您也没有从以前的表中删除该来宾,因此您需要对此进行修改。

您可以使用Array.reduce

let newState = this.state
// let newState = {...this.state} // in case you want everything immutable
newState.tableData = newState.tableData.reduce((acc, table) => 
  if(table.name === tableName) {
    return acc.concat({...table, guests: table.guests.concat(newGuest)})
  } else {
    return acc.concat(table)
  }
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM