spread operator(...)正在es6中的数组中创建额外的字段

时间:2018-02-16 07:11:14

标签: javascript reactjs ecmascript-6 react-redux

我想根据key/value事件在相应的indexed array of objects中嵌入新的onChange对。

但是,它已正确完成但在数组中添加了额外的元素。

原始对象数组:

0:{data: {…}}
1:{data: {…}}
2:{data: {…}}
3:{data: {…}}
4:{data: {…}}

已达成结果:

0:{data: {…}}
1:{data: {…}}
2:{data: {…}, origin: "UK"}
3:{data: {…}, origin: "UK"}
4:{data: {…}}
5:"UK"
6:"UK"

预期结果:

0:{data: {…}}
1:{data: {…}}
2:{data: {…}, origin: "UK"}
3:{data: {…}, origin: "UK"}
4:{data: {…}}

以下是我在循环中执行此操作的代码:

render: (rowData, indexes) => {
          return (
            <SelectField
              id={`origin-${indexes.rowIndex}`}
              defaultValue="US"
              style={{ position: 'absolute' }}
              onChange={text => {
                this.setState(
                  {
                    generalPermitSelectedVehicles: [
                      ...generalPermitSelectedVehicles,
                      (generalPermitSelectedVehicles[
                        indexes.rowIndex
                      ].origin = text),
                    ],
                  },
                  () => {
                    console.log({
                      generalPermitSelectedVehicles: this.state
                        .generalPermitSelectedVehicles,
                    });
                  },
                );
              }}
              menuItems={[
                {
                  label: 'America',
                  value: 'US',
                },
                {
                  label: 'United Kingdom',
                  value: 'UK',
                },
                {
                  label: 'Oman',
                  value: 'Oman',
                },
              ]}
            />
          );
        },

2 个答案:

答案 0 :(得分:5)

像这样写:

this.setState(prevState => {
   let data = [...prevState.generalPermitSelectedVehicles];
   data[indexes.rowIndex].origin = text;
   return {generalPermitSelectedVehicles: data};
})
  

为什么它在你的情况下失败?

因为当你这样做时:

[...arr, (arr[index].origin=10)]

它将做两件事,首先它将更新该索引处的origin值,其次它将在数组末尾添加10(从()返回10)。

检查此代码段:

let arr = [{a:1}, {a:2}, {a:3}];
arr = [...arr, (arr[1].a=500)];  //500 will get added in the last

console.log('new value', arr);

建议:使用更新程序功能(prevState),因为generalPermitSelectedVehicles的下一个状态(值)取决于之前的值。

查看DOC以获取有关 setState updater function 的详细信息。

答案 1 :(得分:3)

您需要更新原始状态而不是追加它。您没有正确使用传播运算符。当您想要根据prevState更新状态时,也可以使用functional setState。你需要做

 this.setState(
              prevState => ({
                generalPermitSelectedVehicles: [
                  ...prevState.generalPermitSelectedVehicles.slice(0, index.rowIndex),
                  {...prevState.generalPermitSelectedVehicles[
                    indexes.rowIndex
                  ], origin: text},
                  ...prevState.generalPermitSelectedVehicles.slice(index.rowIndex + 1)
                ],
              },
              () => {
                console.log({
                  generalPermitSelectedVehicles: this.state
                    .generalPermitSelectedVehicles,
                });
              },
            );

您的方法中的错误是您在传播原始状态后附加更新状态,您需要更新现有状态。

另请查看有关如何update nested state

的答案