我在改变对象吗?

时间:2018-05-24 17:29:38

标签: javascript reactjs

我正在改变状态对象

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 });
};

2 个答案:

答案 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的编辑使用也有效。