Glory Raj
Glory Raj

Reputation: 17691

trying to update an existing object in array of objects using react

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

Answers (2)

Andrew
Andrew

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

CertainPerformance
CertainPerformance

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

Related Questions