Как синхронизировать, чтобы сохранить экземпляр в реагировать? - PullRequest
0 голосов
/ 07 мая 2018

У меня есть магазин в реакции, который содержит @observable names names = []; Теперь я хочу импортировать этот магазин в 3 других магазина, но хочу синхронизировать categories в двух из них. например, если categories изменить в одном магазине, это относится и к другому магазину. Какой лучший способ сделать это?

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

export default class CategoricalStore {
   @observable categories =[];

   @computed get categories () {
      let categories = toJS(this.getCategories());
   }

   @action.bound addCategories (item, e) {
      this.categories.push(item);
   }
}

import CategoricalStore from './CategoricalStore';
export default class store1 {
   this.categories= new CategoricalStore()
}


import CategoricalStore from './CategoricalStore';
export default class store2 {

    this.categories= new CategoricalStore()
}

import CategoricalStore from './CategoricalStore';
export default class store3 {

   this.categories= new CategoricalStore()
}

В приведенном выше примере я хочу синхронизировать store1 и store2 categories.

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Я согласен с Лукасом, но, возможно, я смогу сделать пример проще.

Вы не хотите просто делиться категориями, вы хотите поделиться CategoriesStore , поэтому существует только один источник правды, и все изменения отражаются в одном и том же магазине:

export default class CategoricalStore {
   @observable categories = [];

   @computed get categories() {
      let categories = toJS(this.getCategories());
   }

   @action.bound addCategories (item, e) {
      this.categories.push(item);
   }
}

и в файле реализации вашего магазина (если вы хотите разделить его на несколько файлов, используйте пример @ lucas.

import CategoricalStore from './CategoricalStore';
// here you just create the store once and only once!
var categoryStore = new CategoricalStore();
export default class store1 {
   this.categories = categoryStore;
}

export class store2 {
    this.categories = categoryStore;  //and we just share the same istance.
}

export class store3 {
   this.categories = new CategoricalStore();
}

другое решение - свойства forward forward

Вот пример моего решения для кода, поэтому вам нужно только 2 класса кода для 2 магазинов. Вы могли бы создать интерфейс и позволить всем трем реализовать его, чтобы вы могли использовать их как взаимозаменяемые.

export class StoreInnerShared {
  constructor(rootStore){
     this.rootStore = rootStore;
  }
  getCategories(){
     return this.rootStore.categories;
  } 

   //alternative getter property:
   get categories() {
      return this.rootStore.categories;
   }
}

export class StoreIndependent {
  @observable categories = [];
  getCategories(){
     return this.categories;
  } 
}

new rootStore = new StoreIndependent();
new seperateStore2 = new StoreIndependent();
new innerSharedStore = new StoreInnerShared(rootStore);
0 голосов
/ 09 мая 2018

Вот как бы я подошел к этой проблеме.

Мое решение также распространяется на все будущие свойства каждого магазина. Магазин 1 и Магазин 2 имеют общий список категорий, а Магазин 3 имеет отдельный список.

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

Создайте 3 магазина по мере необходимости со ссылками на Root Store

class Store1 {
  constructor(instance) {
    this.categories = instance.sharedCategories;
  }
}

class Store2 {
  constructor(instance) {
    this.categories = instance.sharedCategories;
  }
}

class Store3 {
  constructor(instance) {
    this.categories = instance.singleCategories;  }
}

Создать магазин категорий, в котором находится массив категорий.

class CategoricalStore {
  @observable categories = [];

  @action.bound
  addCategory(data) {
    this.categories.push(data);
  }
}

Root Store, в котором хранятся оба списка категорий и все 3 магазина.

class RootStore {
  constructor() {
    this.sharedCategories = new CategoricalStore();
    this.singleCategories = new CategoricalStore();
    this.store1 = new Store1(this);
    this.store2 = new Store2(this);
    this.store3 = new Store3(this);
  }
}
export default RootStore;

RootStore.sharedCategories.addCategory(any) - как обновить оба магазина.

Я также предложил пример CodeSandbox , написанный в React.

0 голосов
/ 07 мая 2018

Вы обновили ответ, теперь я понял, что вы хотите сделать. Вероятно, я сделаю что-то вроде этого:

Store1.js

import { observable, computed } from 'mobx';

class Categories {
    @observable categories = [];
    @computed get listCategories(){
        return this.categories;
    }
}
const CategoriesStore = new Categories();
export { Categories, CategoriesStore };

Store2.js

import { CategoriesStore } from './Store1';

class Store2 {
    categories = CategoriesStore.listCategories;
}

Store3.js

import { CategoriesStore } from './Store1';

class Store3 {
    categories = CategoriesStore.listCategories;
}

С помощью следующего кода вы импортируете существующий экземпляр из mobx, экспортированный из Store1, и, если хотите, вы можете создать новый экземпляр с помощью let newStore = new Categories();.

** СТАРЫЙ ОТВЕТ ПЕРЕД ИЗМЕНЕНИЕМ ПОЛЬЗОВАТЕЛЯ **

Если categories уже является наблюдаемым, вам не нужно беспокоиться об этом.

Вам следует создать свойство @computed, получающее значения из categories.

...
import { computed } from 'mobx';
...
@computed get getCategories(){
    return this.categories;
}
...