ReactJS mobx - 不更新可观察数组

问题描述 投票:0回答:2

如果您的商店中有observable列表:

@obserable public Claimslist: IClaim[] = [];

其中IClaim是一个接口,claims是一个IClaim对象的数组

qazxsw poi在其对象中包含一个名为qazxsw poi的变量。每个声明对象都有IClaim变量。

现在你想通过moveOutDate id更新或获取该变量

所以你有2个功能:

得到

id

claim

好吧,但现在当你在 /** * Gets the moveOutDate of a claim by claim ID */ @action getMoveOutDateById = (id: string) => { // Get the claim by id const claim = this.Claimslist.find((element: IClaim) => element.id === sessionStorage.getItem('claim-id')); if (claim) { if (!claim.moveOutDate) { return undefined; } return moment(new Date(claim.moveOutDate)).toDate(); } return undefined; } 中首先使用 /** * Sets moveOutDate in claim by claim ID */ @action public setMoveOutDate = (id: string, date: Date) => { const claim = this.Claimslist.find((element: IClaim) => element.id === id); if (claim) { claim.moveOutDate = date.toString(); } } 时,它可以工作并呈现日期,但是一旦你调用日期组件的getMoveOutDateById render,渲染就不会更新,但是商店会更新,你只能看到变化你刷新页面。

现在我设法通过以下方式解决它:

setMoveOutDate

并添加Claimslist的隐藏输入:

onUpdate

this.Claimslist = this.Claimslist.slice();

为什么会发生,如果整个对象是const {Claimslist} = this.props.claimsStore; 并且用<input type="hidden" value={Claimslist} /> 包裹,为什么它不改变而不使用obserable并有隐藏的输入?

javascript reactjs mobx
2个回答
1
投票

Mobx @action只观察到浅薄的值。意思是说我有slice()然后observable将触发更新,但@observable claims[]将不会claims[0] = something。要解决这个问题,你需要通过在claims[0].foo = bar对象上添加(docs)来使foo也可以观察到。

请考虑以下示例。请注意@observable fooclaim之间的区别。组件完全相同,但Claim1将更新,Claim2将不会。 ClaimView2

ClaimView1

更新:

这是我在评论中给出的解决方案的Demo

import React from "react";
import { render } from "react-dom";
import { observable, action } from "mobx";
import { observer } from "mobx-react";

class Claim1 {
  moveOutDate: Date;
  constructor() {
    this.moveOutDate = new Date();
  }
}

@observer
class ClaimsView1 extends React.Component {
  @observable claims: Claim1[] = [
    new Claim1(),
    new Claim1()
  ];

  @action.bound
  updateClaims(){
    this.claims.forEach(claim => {
      claim.moveOutDate = new Date();
    })
  }

  render() {
    return <div>
      <pre>
        {"ClaimsView1 = \n" + JSON.stringify(this.claims, null, "  ")}
      </pre>
      <button onClick={this.updateClaims}> Update </button>
    </div>
  }
}


class Claim2 {
  @observable moveOutDate: Date;
  constructor() {
    this.moveOutDate = new Date();
  }
}

@observer
class ClaimsView2 extends React.Component {
  @observable claims: Claim2[] = [
    new Claim2(),
    new Claim2()
  ];

  @action.bound
  updateClaims(){
    this.claims.forEach(claim => {
      claim.moveOutDate = new Date();
    })
  }

  render() {
    return <div>
      <pre>
        {"ClaimsView2 = \n" + JSON.stringify(this.claims, null, "  ")}
      </pre>
      <button onClick={this.updateClaims}> Update </button>
    </div>
  }
}

render(
  <>
    <ClaimsView1 />
    <ClaimsView2 />
  </>,
  document.getElementById("root")
);

0
投票

它不完全相同,缺少@observable,如果出现以下情况则相同:

demo
© www.soinside.com 2019 - 2024. All rights reserved.