The spread (...) operator creates additional fields in an array in es6

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

However, this is done correctly, but adding additional elements to the array.

Source 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" 

Expected Result:

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

Below my code does this 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', }, ]} /> ); }, 
+5
source share
2 answers

Write this:

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

Why is his mistake in your case?

Because when you do:

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

It will do two things: first, it will update the source value in this index, and then add 10 (10 from () returned) to the end of the array.

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 the updater (prevState) function because the next state (value) of generalPermitSelectedVehicles depends on the previous value.

Check out the DOC for more information on the setState updater function .

+5
source

You need to update the initial state and not add it. You are not using the operator spread correctly. Also use functional setState when you want to update the state based on prevState. You will 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 of your approach is that you add the updated state after the distribution of the initial state, you need to update the existing one.

Also check out this answer on how update nested state

+3
source

Source: https://habr.com/ru/post/1275390/


All Articles