I have an array of objects
[
{
"0": {
"title": "Jessica Simpson",
"id": "324352342323432",
"url": "image-url.jpg",
"colourScheme": "",
"type": "",
"enabledUnits": ""
},
"1": {
"title": "Bill Murray",
"id": "5qocDvdm9XETFz33p725IG",
"url": "image-url.jpg",
"colourScheme": "",
"type": "",
"enabledUnits": ""
},
}
]
I'm attempting to add update the colourScheme
value inside the object via an onChange event handler.
OnChangeHandler
const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 'type') => (
e: React.ChangeEvent<HTMLInputElement>
) => {
console.log(( e.target.value ))
const itemList = floorPlans.concat();
const index = itemList.findIndex((i) => i.id === floorPlan.id);
itemList.splice(index, 1, {...floorPlans, [property]: e.target.value});
};
But it's being added outside the object. For example... notice "colourScheme": "Black"
is outside.
{
"0": {
"title": "Angeline Espaze",
"id": "5qocDvdm9XETFz33p725IG",
"url": "image-url.jpg",
"colourScheme": "",
"type": "",
"enabledUnits": ""
},
"colourScheme": "Black"
}
]
Where i would like
[
{
"0": {
"title": "Angeline Espaze",
"id": "5qocDvdm9XETFz33p725IG",
"url": "image-url.jpg",
"colourScheme": "Black",
"type": "",
"enabledUnits": ""
},
}
]
I think the issue is with itemList.splice? inside the onChange
CodePudding user response:
The problem is:
You're spreading the wrong thing into the new object, and
You're not calling a state setter.
I wouldn't use splice
for this at all, you can do the object update while copying the array rather than afterward. Instead (see comments):
const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 'type') => (
e: React.ChangeEvent<HTMLInputElement>
) => {
const {value} = e.target;
// Call the state setter; because we're updating state based on existing state, it's
// best to use the callback version
setFloorPlans(floorPlans => {
// Return a new array with a replaced object
return floorPlans.map(entry => {
if (entry.id === floorPlan.id) {
// Create a replacement object
return {...entry, [property]: value};
}
return entry; // No change to this object
});
});
};
That's assuming you're using hooks. If you're using a class component, use this.setState
instead:
const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 'type') => (
e: React.ChangeEvent<HTMLInputElement>
) => {
const {value} = e.target;
// Call the state setter; because we're updating state based on existing state, it's
// best to use the callback version
this.setState(({floorPlans}) => {
// Return a new array with a replaced object
return {floorPlans: floorPlans.map(entry => {
if (entry.id === floorPlan.id) {
// Create a replacement object
return {...entry, [property]: value};
}
return entry; // No change to this object
}});
});
};
CodePudding user response:
Try below code.
const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' |
'type') => ( e: React.ChangeEvent<HTMLInputElement>) => {
let lclfloorPlans = [...floorPlans];
lclfloorPlans.forEach(item => {
for (var key in item) {
if (item[key].id === floorPlan.id) {
item[key][property] = e.target.value;
break;
}
}
});
setFloorPlans(lclfloorPlans); // assign to your state value
};