How to Modify an Object Nested in an Array with React Hooks & Classes

Bird nest

Using React Hooks

Suppose we have the following state of objects nested within an array:


const [ingredients, setIngredients] = useState([
  {item:'banana'}, 
  {item:'avocado'}, 
  {item:'pear'}
]);

In order to edit one of the ingredients without mutating the original state, we need to first make a copy of the original array. We can do this with the spread operator, or .slice():

const newIngredients = [...ingredients];

Or:

const newIngredients = ingredients.slice();

Now, we may be tempted to just run newIngredients[0].item = 'orange', but this would actually mutate the original state. So instead we need to use the following helpful syntax to update the desired ingredient without mutating the original array:

newIngredients[1] = {
  ...newIngredients[1],
  item: 'orange'
};

Now that we’ve updated our newIngredients variable properly, we can use it to set the new state:

setIngredients(newIngredients);

And that’s all folks!

Using React Classes

Below is shown the similar process with React classes:

state = {
  ingredients: [
    {item:'banana'}, 
    {item:'avocado'}, 
    {item:'pear'}
  ]
};
//...
changeIngredients(){
  const {ingredients} = this.state;
  ingredients[1] = {
    ...ingredients[1],
    item: 'orange'
  };
  this.setState({ingredients});
};

Try running the following simplified version of the above example in a JavaScript code runner, and you will see that the original state is not mutated:

const ingredients = [
  {item:'banana'}, 
  {item:'avocado'}, 
  {item:'pear'}
];

const newIngredients = ingredients.slice();

newIngredients[1] = {
  ...newIngredients[1],
  item: 'orange'
};

console.log('ingredients', ingredients);
console.log('newIngredients', newIngredients);
Fruit salad

Fruit by Jo Sonn on Unsplash
Bird Nest by Jon Sailer on Unsplash

Subscribe to new blog posts