Компонент не рендерится при обновлении магазина - Mobx - PullRequest
0 голосов
/ 22 декабря 2018

У меня есть три компонента;Форма, Предварительный просмотр и AppStore.Нажатие кнопки в форме добавляет элемент в магазин.Кажется, это работает нормально, за исключением того, что список в компоненте Preview не обновляется и не перерисовывается при изменении хранилища, даже если оно имеет декоратор @observer.Чего мне не хватает?

Форма имеет функцию кнопки и обработчика, которая добавляет элемент в магазин:

    @inject('AppStore')
    @observer class Form extends React.Component{

      handleAddItem= (item) =>{
        const {AppStore} = this.props;
        AppStore.addItem(item);
        console.log(AppStore.current.items)
      }

      render(){
        return(
              <button onClick={() => this.handleAddItem('Another Item')}>Add Item</button>

        )}
    }

Предварительный просмотр карт через элементы (я использую перетаскиваниетак что мой код может выглядеть немного странно)

  @inject('AppStore')
  @observer class Preview extends React.Component

...

return(
   <ul>
       {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
        ))}
  </ul>)

...

  return <SortableList items={AppStore.current.items} onSortEnd={this.onSortEnd} />;

Вот магазин:

import { observable, action, computed } from "mobx";

class AppStore {
  @observable other = {name: '', desc:'', items: [ 'item 1', 'item 2', 'item 3'], id:''}
  @observable current = {name: '', desc:'', items: [ 'item 1', 'item 2', 'item 3'], id:''}

  @action addItem = (item) => {
    this.current.items.push(item)
  }
}

const store = new AppStore();
export default store;

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Попробуйте заменить ваше действие следующим:

@action addItem = (item) => {
   this.current.items = this.current.items.concat([item]);
}

Здесь вместо использования push для изменения свойства, используйте concat, который используется для объединения двух массивов и возврата целого нового массива сновая ссылка, на которую MobX может реагировать.

0 голосов
/ 22 декабря 2018

Я вполне уверен, что это тот случай, когда MobX не расширяет наблюдаемость вплоть до вашего массива current.items.

Объекты в MobX расширяют наблюдаемость, когда в первый разсконструирован / инициализирован - поэтому current.items является наблюдаемым свойством в том смысле, что если вы измените его значение на какой-то другой примитив, ваш компонент будет перерисован.

Например:

current.items = 1; // changing it from your array to some totally new value
current.items = []; // this _might_ also work because it's a new array

Точно так же, если в AppStore есть наблюдаемая на верхнем уровне items, которую вы меняете, то также будет работать вызов items.push().

class AppStore {
    @observable items = [];

    @action additem = (item) => {
        this.items.push(item);
    }
}

Проблема в вашем случае в том, что items похороненодин уровень глубоко внутри наблюдаемого объекта - поэтому помещение элементов в массив current.items не меняет значение свойства таким образом, который MobX может обнаружить.

Это, по общему признанию, очень запутанно, и распространенные подводные камни MobX иногда трудно понять.

См. также эту строку в документации по объекту:

Можно будет наблюдать только простые объекты.Для непрозрачных объектов считается обязанностью конструктора инициализировать наблюдаемые свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...