【问题标题】:React setState mixing up objects反应 setState 混合对象
【发布时间】:2016-03-15 01:28:25
【问题描述】:

我的组件显示了一个包含在对象中的名字/姓氏/等的联系人

  getInitialState: function () {
    return ({
      contact: {},
      edit: false,
      editedContact: {}
    });
  },

进行ajax调用后,我将信息存储在state.contact和editedcontact中

  success: function (payload) {
    that.setState({ contact: payload.result, editedContact: payload.result});
  }

我有一个 toggleEdit 函数来决定我将呈现什么 - 联系人视图或用于编辑联系人的输入

  toggleEdit: function () {
    this.setState({
      edit: true,
    });
  },

   render: function () {
    if(!this.state.edit){
      var output = (
        <div>
          <div className="panel panel-default">
            <div className="panel-heading">{this.state.contact.firstName</div>
            ...
        </div>
      );
    } else {
      output = (
        <span className="cancel" onClick={this.cancelEdit}>Cancel</span>
          <form onSubmit={this.handleSubmit}>
                  <input className="form-control" id="first-name" type="text" onChange={this.handleChange.bind(this, "firstName")} value={this.state.editedContact.firstName}/>
            ...

表单的值已经与我的editedContact同步,以便于用户体验和onChange,他们更新了editedContact

  handleChange: function (paremeter, e) {
    console.log(this.state.contact.lastName);
    console.log(this.state.editedContact.lastName);
    var editedContact = this.state.editedContact;
    editedContact[paremeter] = e.target.value;
    this.setState({editedContact: editedContact});
  }

我的 cancelEdit 将 edit 状态更改回 true 以再次查看联系人,但我不明白为什么我仍然在此视图中看到对 editContact 所做的更改。我的handleChange 只更新editedContact 状态,而不是联系人状态,那么为什么我会通过控制台日志看到对联系人状态的更改?

【问题讨论】:

    标签: reactjs state onchange


    【解决方案1】:

    我认为这是由于突变错误。尤其是这些行:

    success: function (payload) {
        that.setState({ contact: payload.result, editedContact: payload.result});
    }
    

    您正在做的是将这两个键中的每一个设置为 REFERENCE payload.result。意思是,如果你在哪里更改payload,那么contact 和editedContact 都会发生突变。当您执行 var editedContact = this.state.editedContact 然后更改参数时,您就是这样做的。

    要测试是否发生这种情况,请在设置之前尝试克隆有效负载:

    success: function (payload) {
        that.setState({ contact: {...payload.result}, editedContact: {...payload.result}});
    }
    

    或者没有展开运算符:

    success: function (payload) {
        that.setState({ 
            contact: Object.assign({}, payload.result), 
            editedContact: Object.assign({}, payload.result)
        });
    }
    

    让我们知道这是否可行!

    【讨论】:

    • 哇!!!惊人的!!谢谢你!我使用了您的第二个建议,通过构建payload.result 的副本,这与第一个基本相同吗?
    • 是的,它将第二个中的所有值“分配”给n 对象到第一个对象。所以它改变了第一个参数,在我们的例子中是一个空的新对象。第一个做同样的事情,但它是一个尚未发布的 JavaScript 2016 功能(您需要使用 Babel 之类的东西进行转译,stage-0 预设它才能工作)
    • 只是“语法糖”让代码更精简更简洁
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2018-12-14
    相关资源
    最近更新 更多