javascript - ReactJS mobx - 不更新可观察数组

标签 javascript reactjs mobx

如果你有一个 observable在您的商店中列出:

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

哪里IClaim是一个接口(interface),claimsIClaim 的数组对象

IClaim在其对象中包含一个名为 moveOutDate 的变量 每个 claim 对象都有 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 onUpdate日期组件的渲染不会更新,但商店会更新,只有刷新页面才能看到更改。

现在我设法解决了这个问题,方法是:

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

并添加 Claimslist 的隐藏输入:

const {Claimslist} = this.props.claimsStore;

<input type="hidden" value={Claimslist} />

如果整个对象是obserable,为什么会这样?并用 @action 包裹为什么不使用 slice() 不改变并有一个隐藏的输入?

最佳答案

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

考虑以下示例。请注意 Claim1Claim2 之间的区别。组件完全相同,但 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")
);


更新:

这是一个 demo对于我在评论中给出的解决方案

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

interface IClaim {
  moveOutDate: Date;
}

@observer
class ClaimsView extends React.Component<{claims: IClaim[]}> {
  @observable claims: IClaim[] = this.props.claims.map(claim => observable(claim))

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

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


render(
  <ClaimsView claims={[
    { moveOutDate: new Date() },
    { moveOutDate: new Date() }
  ]} />,
  document.getElementById("root")
);

关于javascript - ReactJS mobx - 不更新可观察数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55262053/

相关文章:

javascript - 为什么当 jquery NiceSelect 展开时我的自定义滚动条不更新?

javascript - 使用 d3 拖动 SVG <g> 元素会导致闪烁问题

reactjs - react : Function components cannot be given refs when displaying a modal

reactjs - 为什么 Redux 将调度传递到操作的返回函数中?

javascript - Promise 的返回值 - { AsyncStorage } React-Native

javascript - 为什么 parseInt(1/0, 19) 返回 18?

javascript - 使用 logstash 和 elasticsearch

javascript - 如何在 react 中将json推送到Mobx的数组状态

javascript - react native 和 MobX : How to create a global store?

javascript - 如何从 mobx 对象中获取普通对象?