Reputation: 17691
I have array of objects and the format is like this
addedOpaqueMaterials = [{
conductivity: 1
density: 1
id: "1"
......
......
},
{
conductivity: 2
density: 1
id: "2",
......
......
}]
and from the react state i am getting updated object with the id= 2
like as this below,
{
conductivity: 4
density: 23
id: "2",
......
......
}
and i am looking to update the object in main array with these values, what could be the best way to update, below is the code related to that.
const handleDrawerSubmit = values => {
const addedOpaqueMaterials = formValues.constructionSet?.opaqueMaterials; // array of objects
const updatedMaterial = addedOpaqueMaterials.find(i => i.id === values?.opaqueMaterial?.id);
// values?.opaqueMaterial is having updated object
// Object.assign(updatedMaterial, values.opaqueMaterial); getting an error
};
Now I would like to merge values.Opaquematerial
object into addedOpaqueMaterials
which is array of objects, what could be the best way to achieve this?
Many thanks
Upvotes: 1
Views: 164
Reputation: 7545
This is just a regular algorithm challenge. No need to otherthink it. The only requirement that react demands out of you is that it needs to be a new array. Array#map
works perfectly fine.
const materialExists = addedOpaqueMaterials.some(({id}) => id === values?.opaqueMaterial?.id)
let updatedMaterial
if (materialExists) {
updatedMaterial = addedOpaqueMaterials.map(material => {
if (material.id === values?.opaqueMaterial?.id) {
return values.opaqueMaterial
}
return material
})
} else {
updatedMaterial = [...addedOpaqueMaterials, values.opaqueMaterial]
}
Upvotes: 2
Reputation: 370659
Instead of using .find
, use .findIndex
first, so that you can replace the object in the array with the new object. (Remember not to use Object.assign
in React when the first parameter is stateful, because that'd result in a state mutation)
You should also check that all of these objects exist first before trying to update.
if (!formValues.constructionSet || !values || !values.opaqueMaterial) {
return;
}
const newMat = values.opaqueMaterial;
const index = addedOpaqueMaterials.findIndex(mat => mat.id === newMat.id);
if (index === -1) {
// Add to the end of the existing array:
const newOpaqueMaterials = [
...addedOpaqueMaterials,
newMat
];
// put newOpaqueMaterials into state
} else {
// Replace the object in the state array with the new object:
const newOpaqueMaterials = [
...addedOpaqueMaterials.slice(0, index),
newMat,
...addedOpaqueMaterials.slice(index + 1)
];
// put newOpaqueMaterials into state
}
Upvotes: 1