patternreactCritical
Updating an object with setState in React
Viewed 0 times
setstateupdatingreactwithobject
Problem
Is it at all possible to update object's properties with
Something like:
I have tried:
and this:
The first results in a syntax error and the second just does nothing. Any ideas?
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
1- Simplest one:
First create a copy of
Instead of using
2- Using spread syntax:
Note:
Updating nested state object:
Assume you have defined state as:
To update
Updating array of objects:
Let;s assume you have a todo app, and you are managing the data in this form:
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
Suggestion: If object doesn't have a unique value, then use array index.
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.