【问题标题】:Why is updating one object in state updating both?为什么更新状态中的一个对象同时更新两者?
【发布时间】:2019-11-08 18:08:10
【问题描述】:

这让我发疯 - 我有一个供用户更新帐户信息的表单,我想在用户更新任何输入时显示“完成后记得保存”通知。为此,我将“用户”对象存储在状态中,同时将“原始用户”对象存储在状态中。但是当我更新“用户”对象时,它也会更新“原始用户”对象!

简化代码:

我从数据库中获取用户详细信息,并设置状态:

this.setState({loaded: true, user: data.user, originalUser: data.user});

那么我对状态进行任何更新的唯一地方就是这个函数:

onInputChange = (input, val) => {
   let user = this.state.user;
   user[input] = val;
   this.setState({user: user});
    console.log(this.state.user);
    console.log(this.state.originalUser);
}

但控制台会记录发生在 BOTH 上的更新。例如,如果输入是“first”并且值最初是“John”,我将其更改为“Johnny”,那么“user”和“originalUser”的“first”都是“Johnny”。为什么 originalUser 在这里更新?

【问题讨论】:

  • 修改一个修改两个,因为它们是同一个对象。我认为您需要了解 JavaScript 如何引用/对象/等。在继续 React 之前多做一些工作。此外,您不应该改变(修改)存储在您的状态中的对象。 user[input] = val; // <-- this is bad.
  • 我创建了一个新变量“user”,它是存储在状态中的内容的副本,然后我修改它,然后更新状态。那么,修改 state.user 对象的正确方法是什么?

标签: reactjs state


【解决方案1】:

赋值运算符不会创建对象的副本,它只会分配对它的引用。 如果您的对象没有深度嵌套,扩展运算符会有所帮助

this.setState({loaded: true, user: {...data.user}, originalUser: {...data.user}});

也不要直接改变状态。改用这个:

let user = {...this.state.user};
user[input] = val;
this.setState({user: user});

【讨论】:

  • 谢谢!仍然有点困惑,因为我认为当您在状态中有嵌套对象时使用了扩展运算符。在这种情况下,“user”和“originalUser”都处于顶层,所以我仍然对为什么更新 state.user 会更新 state.originalUser 感到困惑。不管怎样,你的建议确实奏效了,只是想弄清楚它。
  • @seeker70 因为 state.user 和 state.originalUser 指向同一个对象。所以当你修改 state.user 的时候,你也同时修改了 state.originalUser。
  • 这仍然不是一个完整的解决方案。 onInputChange 仍在改变状态对象,而不是使用 setState 来更新它。
  • 更新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 2022-01-04
  • 2020-05-02
  • 2021-06-04
相关资源
最近更新 更多