HiveBrain v1.2.0
Get Started
← Back to all entries
patternreactCritical

Updating an object with setState in React

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
setstateupdatingreactwithobject

Problem

Is it at all possible to update object's properties with setState?

Something like:

this.state = {
   jasper: { name: 'jasper', age: 28 },
}


I have tried:

this.setState({jasper.name: 'someOtherName'});


and this:

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


The first results in a syntax error and the second just does nothing. Any ideas?

Solution

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

1- Simplest one:

First create a copy of jasper then, make 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 create 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:

Let;s 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.

Code Snippets

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
})
let jasper = { ...prevState.jasper };
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
    }
}))
this.state = {
  food: {
    sandwich: {
      capsicum: true,
      crackers: true,
      mayonnaise: true
    },
    pizza: {
      jalapeno: true,
      extraCheese: false
    }
  }
}
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
    }
  }
}))

Context

Stack Overflow Q#43638938, score: 1050

Revisions (0)

No revisions yet.