为什么状态更新会覆盖现有数据值?

时间:2020-10-13 18:34:27

标签: javascript reactjs

下面,我尝试获取用户数据当前状态的副本,以及从键值对都为空的json文件中提取的新发票模板的副本。

然后我将模板的invoiceID更改为比idx大1(这是从子组件发送的数字值,该数字值是状态中所有发票的长度)。

最后,我获取了用户数据的副本并添加了新模板,然后将新用户数据保存回状态,以便可以在列表中进行更新。

  createInvoice = idx => {
    let newUserData = this.state.userData;
    let template = UsersJSON[0].invoices[0];

    template.invoiceID = idx + 1;
    newUserData.invoices.push(template);

    this.setState({
      userData: newUserData
    });
  }

这是我登录时所有数据的当前状态: enter image description here

单击“新发票+”一次后: enter image description here

在我多次单击“新发票”后,问题开始出现: enter image description here

仅所有新发票ID都会不断更新为最新的ID。我真的不知道为什么会这样。任何帮助将不胜感激!

指向我在github上的项目的链接(在发票分支上查看,而不是主文档): https://github.com/Brent-W-Anderson/invoice-pdf/tree/invoices

2 个答案:

答案 0 :(得分:2)

问题

  1. 您没有为状态和反应对帐正确创建新的数组引用。
  2. 您还正在变异模板引用对象。

代码

createInvoice = idx => {
  let newUserData = this.state.userData; // <-- saved state reference
  let template = UsersJSON[0].invoices[0];

  template.invoiceID = idx + 1; // <-- template mutation
  newUserData.invoices.push(template); // <-- mutated state

  this.setState({
    userData: newUserData // <-- saved state reference back into state
  });
}

解决方案

创建要更新的所有状态的浅表副本。

createInvoice = idx => {
  let newInvoices = [...this.state.userData.invoices]; // <-- create a new array reference
  let template = {
    ...UsersJSON[0].invoices[0], // <-- create new template object reference
  };

  template.invoiceID = idx + 1;
  newInvoices.push(template);

  this.setState({
    userData: {
      ...state.userData,
      invoices: newInvoices,
    }
  });
}

添加到状态的一种更为反应的方法是映射来自先前状态的数据,并在模板中散布,因此您也不会变异 it

createInvoice = idx => {
  this.setState(prevState => ({
    userData: {
      ...prevState.userData,
      invoices: [
        ...prevState.userData.invoices,
        {
          ...UsersJSON[0].invoices[0],
          invoiceID: idx + 1,
        },
      ],
    },
  }));
}

答案 1 :(得分:0)

要在更新状态对象之前复制状态对象(在JS数组中为对象)。也许let newUserData = [...this.state.userData]是避免此错误的方法,但您可能需要“深层副本”。

有关此主题的更多信息,请参见https://dev.to/andyrewlee/cheat-sheet-for-updating-objects-and-arrays-in-react-state-48np