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?
Updating the object properties To update the object properties, we need to use the spread operator in setState method. class App extends Component { state = { user: { name: "John", age: 19, active: true } }; handleAge = () => { this. setState({ user: { ... this.
Before updating the value of the state, we need to build an initial state setup. Once we are done with it, we use the setState() method to change the state object. It ensures that the component has been updated and calls for re-rendering of the component.
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.
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 } } }))
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With