ReactJS mobx - не обновляет наблюдаемый массив - PullRequest
0 голосов
/ 20 марта 2019

Если у вас есть список observable в вашем магазине:

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

где IClaim - интерфейс, claims - массив IClaim объектов

IClaim содержит переменную в своем объекте с именем moveOutDate Каждый объект заявки имеет переменную id.

А теперь вы хотите обновить или получить эту переменную по claim id

Итак, у вас есть 2 функции:

Получить

  /**
   * 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();

и добавление скрытого ввода списка заявок:

const {Claimslist} = this.props.claimsStore;

и

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

Почему это происходит, если весь объект равен obserable и заключен в @action, почему он не изменяется без использования slice() и скрытого ввода?

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Mobx observable только наблюдает мелкие значения.То есть, допустим, у меня есть @observable claims[], тогда claims[0] = something запустит обновление, но claims[0].foo = bar не будет (документы) .Чтобы это исправить, вам нужно сделать также foo наблюдаемым, добавив @observable foo к claim объекту.

Рассмотрим следующий пример.Обратите внимание на разницу между Claim1 и Claim2.Компоненты точно такие же, но ClaimView2 обновится, а ClaimView1 - нет. Демо

<code>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, "  ")}
      
Обновление }} class Claim2 {@observable moveOutDate: Date;constructor () {this.moveOutDate = new Date ();}} @observer class ClaimsView2 расширяет React.Component {@observable притязания: Claim2 [] = [new Claim2 (), new Claim2 ()];@ action.bound updateClaims () {this.claims.forEach (Prache => {Clamp.moveOutDate = new Date ();})} render () {return
        {"ClaimsView2 = \n" + JSON.stringify(this.claims, null, "  ")}
      
Обновление
}}визуализация (<>, document.getElementById ("root"));


Обновление:

Вот демо для решения, которое я дал в комментариях

<code>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, "  ")}
      
Обновление }} render (, document.getElementById ("root"));
0 голосов
/ 20 марта 2019

Это не совсем то же самое, отсутствует @observable, оно будет таким же, если:

class Claim1 {
  @observable moveOutDate: Date;
...
...