为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

万千封印 2023-05-11 16:43:01
下面我尝试获取用户数据当前状态的副本,以及从 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    });  }这是我登录时所有数据的当前状态:在我点击 New Invoice + 一次之后:在我多次点击 New Invoice + 后,问题开始出现:只有所有新的发票 ID 会不断更新为最新和最好的 ID。我真的不知道为什么会这样。任何帮助,将不胜感激!我在 github 上的项目的链接(查看 invoices 分支,而不是 master): https ://github.com/Brent-W-Anderson/invoice-pdf/tree/invoices
查看完整描述

2 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

问题

  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,

    }

  });

}

添加到状态的一种稍微更反应性的方法是映射来自先前状态的数据并在模板中传播,这样您也不会改变它。


createInvoice = idx => {

  this.setState(prevState => ({

    userData: {

      ...prevState.userData,

      invoices: [

        ...prevState.userData.invoices,

        {

          ...UsersJSON[0].invoices[0],

          invoiceID: idx + 1,

        },

      ],

    },

  }));

}


查看完整回答
反对 回复 2023-05-11
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

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

查看完整回答
反对 回复 2023-05-11
  • 2 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信