state = {
selectedHero: { id: "", name: "", saying: "" }
}
使用此方法
handleChange = e => {
let selectedHero = this.state.selectedHero;
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
我应该写这样的东西吗?
handleChange = e => {
let selectedHero = { ...this.state.selectedHero };
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
答案 0 :(得分:4)
是和否。你没有改变this.state
,但你正在改变一个this.state
引用的对象。你不应该在React做什么。
我应该写这样的东西吗?
<强>概强>;因为这涉及根据状态(selectedHero
的其他属性)更新状态,所以must use the callback version of setState
。由于这意味着在handleChange
返回后使用合成事件中的属性,我们需要预先获取它们:
handleChange = e => {
const {name, value } = e.target;
this.setState(prevState => {
let selectedHero = { ...prevState.selectedHero };
selectedHero[name] = value;
return { selectedHero };
})
};
如果您不使用回调版本,那么事情似乎会在很多时候起作用,并且当您对selectedHero
进行重叠状态更新时会失败(请记住状态更新是异步的);一个人会踩到另一个。
如果您愿意,还可以在属性传播后使用计算属性名称压缩它:
handleChange = e => {
const {name, value} = e.target;
this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};
甚至抛出一些参数解构:
handleChange = ({target: {name, value}}) => {
this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};
(是的,解构将在handleChange
返回之前发生。它发生在handleChange
中的显式代码运行之前。)
答案 1 :(得分:0)
是的,您正在改变selectedHero
对象。你应该这样做:
handleChange = e => {
let selectedHero = Object.assign({}, this.state.selectedHero);
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
Object.assign
调用将创建新对象,以便不修改原始的selectedHero对象
修改:您对ES2018 spread syntax的编辑使用也有效。