[英]am I mutating object?
am I mutating state object 我正在改变状态对象吗
state = {
selectedHero: { id: "", name: "", saying: "" }
}
with this method 用这种方法
handleChange = e => {
let selectedHero = this.state.selectedHero;
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
should I write something like this? 我应该写这样的东西吗?
handleChange = e => {
let selectedHero = { ...this.state.selectedHero };
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
Yes and no. 是的,没有。 You're not mutating
this.state
, but you are mutating an object this.state
refers to. 您不是要
this.state
,而是要this.state
引用的对象。 Which you shouldn't do in React. 在React中不应该这样做。
should I write something like this?
我应该写这样的东西吗?
Almost ; 差不多 ; since that involves updating state based on state (the other properties of
selectedHero
), you must use the callback version of setState
. 由于这涉及基于状态(
selectedHero
的其他属性)来更新状态,因此必须使用setState
的回调版本 。 Since that means using properties from the synthetic event after handleChange
returns, we'll need to grab them up-front: 由于这意味着在
handleChange
返回后使用合成事件中的属性,因此我们需要handleChange
获取它们:
handleChange = e => {
const {name, value } = e.target;
this.setState(prevState => {
let selectedHero = { ...prevState.selectedHero };
selectedHero[name] = value;
return { selectedHero };
})
};
If you don't use the callback version, things will appear to work much of the time, and fail when you have overlapping state updates to selectedHero
(remember that state updates are asynchronous); 如果您不使用回调版本,则大多数情况下似乎会正常工作,并且在对
selectedHero
进行重叠的状态更新时会失败(请记住状态更新是异步的); one will stomp on the other. 一个会脚另一个。
If you like, you can also condense it by using a computed property name after the property spread: 如果您愿意,还可以通过在属性分布后使用计算的属性名称来压缩它:
handleChange = e => {
const {name, value} = e.target;
this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};
and even throw in some parameter destructuring: 甚至抛出一些参数解构:
handleChange = ({target: {name, value}}) => {
this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};
(Yes, the destructuring will happen before handleChange
returns. It happens before your explicit code in handleChange
runs at all.) (是的,解构将在
handleChange
返回之前发生。它发生在handleChange
的显式代码handleChange
运行之前。)
Yes, you are mutating the selectedHero
object. 是的,您正在变异
selectedHero
对象。 You should do something like this: 您应该执行以下操作:
handleChange = e => {
let selectedHero = Object.assign({}, this.state.selectedHero);
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
The Object.assign
call will create a new object, so that your original selectedHero object is not modified Object.assign
调用将创建一个新对象,这样就不会修改您原来的selectedHero对象。
Edit: Your edited use of the ES2018 spread syntax works too. 编辑:您对ES2018传播语法的编辑使用也可以使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.