最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - spread operator (...) is creating extra fields in array in es6 - Stack Overflow

programmeradmin1浏览0评论

I wanted to embed a new key/value pair in the respective indexed array of objects based on an onChange event.

However, it is done correctly but adding extra elements in the array.

Original array of objects:

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

Achieved result:

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

Intended result:

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

Below is my code doing it in a loop:

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',
                },
              ]}
            />
          );
        },

I wanted to embed a new key/value pair in the respective indexed array of objects based on an onChange event.

However, it is done correctly but adding extra elements in the array.

Original array of objects:

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

Achieved result:

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

Intended result:

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

Below is my code doing it in a loop:

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',
                },
              ]}
            />
          );
        },
Share Improve this question asked Feb 16, 2018 at 7:11 OwaisOwais 8602 gold badges13 silver badges32 bronze badges 3
  • ... is not an operator! – Felix Kling Commented Feb 17, 2018 at 16:00
  • What is it called, actually? What's its purpose? Can you elaborate it? We can learn from your statement. Thanks – Owais Commented Feb 19, 2018 at 8:32
  • I have explained all that in the post I linked to. – Felix Kling Commented Feb 19, 2018 at 15:26
Add a ment  | 

2 Answers 2

Reset to default 5

Write it like this:

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

Why its failing in your case?

Because when you do:

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

It will do two things, first it will update the value of origin at that index, second it will add 10 (returned 10 from ()) at the end of array also.

Check this snippet:

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);

Suggestion: Use updater function (prevState) because next state (value) of generalPermitSelectedVehicles is dependent on previous value.

Check the DOC for more details about setState updater function.

You need to update the original state and not append it. You are not using spread operator correctly. Also make use of functional setState when you want to update state based on prevState. You would need to do

 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,
                });
              },
            );

The error in your approach is that you are appending the updated state after spreading the original state, you need to update the existing instead.

Also check this answer on how to update nested state

发布评论

评论列表(0)

  1. 暂无评论