目前,我正在和一些用户编辑器一起玩。 当然,我碰到过反应原理:“永远不要直接改变this.state”
假设下面的代码片段是一个简单的用户编辑器(未显示:未将用户对象作为按钮保存单击时的json推送到Web服务):
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;
在onChange方法中,我尝试了三种不同的方法来更新当前用户对象:
每种方法都能按预期工作。
在这种情况下,不同方法的缺点是什么?
当然,如果我仅通过引用更新用户对象,则setState的空调用也将反映更改。
setState如何处理/评估更新的状态对象以进行渲染吗?
br,苏西
答案 0 :(得分:0)
实际上没有一种理想的方式来处理嵌套状态,要么有一个通用函数来处理对象的所有更新,要么编写很多单独的函数来处理应如何更新每个值。每个人都有其优点和缺点。
您的问题询问如何最好地克隆对象。这确实是一个单独的问题(answered here),但我建议您使用object spread语法,如下所示:
const user = {
name: 'me',
parents: {
mother: 'mary',
father: 'john',
},
hobbies: [{
name: 'soccer',
location: 'home'
},
{
name: 'tennis',
location: 'home'
}
]
};
const addUserHobby = (user, newHobby) => ({
...user,
hobbies: [
...user.hobbies,
newHobby
]
})
const updatedUser = addUserHobby(user, {
name: 'hockey',
location: 'home'
})
console.dir(updatedUser)