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

下面我尝试获取用户数据当前状态的副本,以及从 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

    });

  }

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

http://img1.mukewang.com/645caaa70001927006570231.jpg

在我点击 New Invoice + 一次之后:

http://img4.mukewang.com/645caab30001d27606540249.jpg

在我多次点击 New Invoice + 后,问题开始出现:

http://img.mukewang.com/645caac0000118d206550275.jpg

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

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


万千封印
浏览 106回答 2
2回答

12345678_0001

问题您没有正确地为状态和反应协调创建新的数组引用。您还改变了模板引用对象。代码createInvoice = idx => {&nbsp; let newUserData = this.state.userData; // <-- saved state reference&nbsp; let template = UsersJSON[0].invoices[0];&nbsp; template.invoiceID = idx + 1; // <-- template mutation&nbsp; newUserData.invoices.push(template); // <-- mutated state&nbsp; this.setState({&nbsp; &nbsp; userData: newUserData // <-- saved state reference back into state&nbsp; });}解决方案创建您打算更新的所有状态的浅表副本。createInvoice = idx => {&nbsp; let newInvoices = [...this.state.userData.invoices]; // <-- create a new array reference&nbsp; let template = {&nbsp; &nbsp; ...UsersJSON[0].invoices[0], // <-- create new template object reference&nbsp; };&nbsp; template.invoiceID = idx + 1;&nbsp; newInvoices.push(template);&nbsp; this.setState({&nbsp; &nbsp; userData: {&nbsp; &nbsp; &nbsp; ...state.userData,&nbsp; &nbsp; &nbsp; invoices: newInvoices,&nbsp; &nbsp; }&nbsp; });}添加到状态的一种稍微更反应性的方法是映射来自先前状态的数据并在模板中传播,这样您也不会改变它。createInvoice = idx => {&nbsp; this.setState(prevState => ({&nbsp; &nbsp; userData: {&nbsp; &nbsp; &nbsp; ...prevState.userData,&nbsp; &nbsp; &nbsp; invoices: [&nbsp; &nbsp; &nbsp; &nbsp; ...prevState.userData.invoices,&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...UsersJSON[0].invoices[0],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; invoiceID: idx + 1,&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; ],&nbsp; &nbsp; },&nbsp; }));}

蝴蝶不菲

你想在更新之前复制一个状态对象(在 JS 数组中是对象)。也许let newUserData = [...this.state.userData]是避免此错误的方法,但您可能需要“深拷贝”。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript