Updating an object with setState in React Updating an object with setState in React reactjs reactjs

Updating an object with setState in React


There are multiple ways of doing this, since state update is a async operation, so to update the state object, we need to use updater function with setState.

1- Simplest one:

First create a copy of jasper then do the changes in that:

this.setState(prevState => {  let jasper = Object.assign({}, prevState.jasper);  // creating copy of state variable jasper  jasper.name = 'someothername';                     // update the name property, assign a new value                   return { jasper };                                 // return new object jasper object})

Instead of using Object.assign we can also write it like this:

let jasper = { ...prevState.jasper };

2- Using spread syntax:

this.setState(prevState => ({    jasper: {                   // object that we want to update        ...prevState.jasper,    // keep all other key-value pairs        name: 'something'       // update the value of specific key    }}))

Note: Object.assign and Spread Operator creates only shallow copy, so if you have defined nested object or array of objects, you need a different approach.


Updating nested state object:

Assume you have defined state as:

this.state = {  food: {    sandwich: {      capsicum: true,      crackers: true,      mayonnaise: true    },    pizza: {      jalapeno: true,      extraCheese: false    }  }}

To update extraCheese of pizza object:

this.setState(prevState => ({  food: {    ...prevState.food,           // copy all other key-value pairs of food object    pizza: {                     // specific object of food object      ...prevState.food.pizza,   // copy all pizza key-value pairs      extraCheese: true          // update value of specific key    }  }}))

Updating array of objects:

Lets assume you have a todo app, and you are managing the data in this form:

this.state = {  todoItems: [    {      name: 'Learn React Basics',      status: 'pending'    }, {      name: 'Check Codebase',      status: 'pending'    }  ]}

To update the status of any todo object, run a map on the array and check for some unique value of each object, in case of condition=true, return the new object with updated value, else same object.

let key = 2;this.setState(prevState => ({  todoItems: prevState.todoItems.map(    el => el.key === key? { ...el, status: 'done' }: el  )}))

Suggestion: If object doesn't have a unique value, then use array index.


This is the fastest and the most readable way:

this.setState({...this.state.jasper, name: 'someothername'});

Even if this.state.jasper already contains a name property, the new name name: 'someothername' with be used.


Use spread operator and some ES6 here

this.setState({    jasper: {          ...this.state.jasper,          name: 'something'    }})