ReactJS mobx - не обновляет наблюдаемый массив

Пример кода для дифференциации ОС с помощью python:

from sys import platform as _platform

if _platform == "linux" or _platform == "linux2":
   # linux
elif _platform == "darwin":
   # MAC OS X
elif _platform == "win32":
   # Windows
elif _platform == "win64":
    # Windows 64-bit
0
задан Ben Beri 20 March 2019 в 13:37
поделиться

2 ответа

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

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

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")
);


Обновление:

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

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")
);
0
ответ дан Devansh J 20 March 2019 в 13:37
поделиться

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

class Claim1 {
  @observable moveOutDate: Date;
...
0
ответ дан Mario 20 March 2019 в 13:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: