Currently i am playing with some user editor in react. Of course i came across reacts principle: 'Never mutate this.state directly'
Suppose the following snippet for a simple user editor (what isn't shown: the user object will be pushed to a web service as json on buttonSave click):
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {
user: {
name: 'me',
parents: {
mother: 'mary',
father: 'john',
},
hobbies: [
{
name: 'soccer',
location: 'home'
},
{
name: 'tennis',
location: 'home'
}
]
}
};
}
onChange(e) {
let user = this.state.user; // 1 - no copy - reference
//let user = {...this.state.user}; // 2 - shallow copy
//let user = JSON.parse(JSON.stringify(this.state.user)); // 3 - deep copy
switch (e.target.dataset.ptype) {
case 'me':
user.name = e.target.value;
break;
case 'mother':
user.parents.mother = e.target.value;
break;
case 'father':
user.parents.father = e.target.value;
break;
case 'hobby':
user.hobbies[1].name = e.target.value;
break;
default:
break;
}
this.setState({
user: user
});
}
render() {
return (
<div>
<div><input data-ptype='me' onChange={this.onChange} value={this.state.user.name}/>{this.state.user.name}</div>
<div><input data-ptype='mother' onChange={this.onChange} value={this.state.user.parents.mother}/>{this.state.user.parents.mother}</div>
<div><input data-ptype='father' onChange={this.onChange} value={this.state.user.parents.father}/>{this.state.user.parents.father}</div>
<div><input data-ptype='hobby' onChange={this.onChange} value={this.state.user.hobbies[1].name}/>{this.state.user.hobbies[1].name}</div>
<div><pre>{JSON.stringify(this.state.user, null, 2)}</pre></div>
</div>
)
}
}
export default App;
In the onChange method i tried three different approaches for updating the current user object:
- Reference
- Spread Operator
- JSON.stringify
Every approach works as expected.
What are the drawbacks in this scenario of the different approaches ?
Sure, if i only update the user object via reference a empty call of setState will reflect the changes too.
Is there any overview available how setState handles/evaluates an updated state object for rendering ?
br, Susi