Как отслеживать вложенный объект в магазине MobX

Давайте останемся, у меня есть этот myObject, загруженный через вызов API:

myObject = {
  fieldA: { details: 'OK', message: 'HELLO' },
  fieldB: { details: 'NOT_OK', message: 'ERROR' },
}

Могут изменяться только детали и сообщение каждого поля. Я хочу, чтобы этот объект можно было наблюдать в магазине MobX (какие свойства будут определены ниже). У меня есть простой компонент React, который считывает два поля из магазина:

@observer
class App extends Component {
  store = new Store();

  componentWillMount() {
    this.store.load();
  }

  render() {
    return (
      <div>
        {this.store.fieldA && <p>{this.store.fieldA.details}</p>}
        {this.store.fieldB && <p>{this.store.fieldB.details}</p>}
      </div>
    );
  }
}

Я прочитал эту страницу, пытаясь понять, на что реагирует MobX, но все еще не получил ясная идея. В частности, какой из 4 магазинов, представленных ниже, будет работать и почему?

1/

class Store1 = {
  @observable myObject = {};

  @action setMyObject = object => {
    this.myObject = object;
  }

  load = () => someAsyncStuff().then(this.setMyObject);
}

2/

class Store2 = {
  @observable myObject = {};

  @action setMyObject = object => {
    this.myObject.fieldA = object.fieldA;
    this.myObject.fieldB = object.fieldB;
  }

  load = () => someAsyncStuff().then(this.setMyObject);
}

3/

class Store3 = {
  @observable myObject = { fieldA: {}, fieldB: {} };

  @action setMyObject = object => {
    this.myObject = object;
  }

  load = () => someAsyncStuff().then(this.setMyObject);
}

4/

class Store4 = {
  @observable myObject = { fieldA: {}, fieldB: {} };

  @action setMyObject = object => {
    this.myObject.fieldA = object.fieldA;
    this.myObject.fieldB = object.fieldB;
  }

  load = () => someAsyncStuff().then(this.setMyObject);
}

person jeanpaul62    schedule 22.12.2017    source источник


Ответы (1)


Все вышеперечисленное будет работать, кроме решения 2. Это потому, что, как описано в документации Mobx об объектах:

При передаче объектов через observable будут наблюдаться только те свойства, которые существуют на момент создания объекта observable. Свойства, добавленные к объекту позже, не станут наблюдаемыми, если не используется extendObservable.

В первом решении вы повторно назначаете объекту свойства, уже существующие в возвращенном объекте. В 3 и 4 вы инициализировали объект этими двумя свойствами, чтобы он работал.

Также я думаю, что в вашем примере компонента вы хотели использовать его вот так (иначе это никак не сработает):

render() {
    const { myObject } = this.store;

    return (
      <div>
        {myObject && myObject.fieldA && <p>{myObject.fieldA.details}</p>}
        {myObject && myObject.fieldB && <p>{myObject.fieldB.details}</p>}
      </div>
    );
}
person Doron Brikman    schedule 04.01.2018