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',
},
]}
/>
);
},
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With