Как синхронизировать, чтобы сохранить экземпляр в реагировать?
У меня есть магазин в реакции, который содержит @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 ответа
Вот как я бы подошел к этой проблеме.
Мое решение также распространяется на все будущие свойства каждого магазина. Магазин 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);
}
}
Корневой магазин, который содержит как списки категорий, так и все 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.
Вы обновили ответ, теперь я понял, что вы хотите сделать. Вероятно, я сделаю что-то вроде этого:
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;
}
Я согласен с Лукасом, но, возможно, я могу сделать пример проще.
Вы не просто хотите делиться категориями, вы хотите делиться хранилищем категорий, поэтому существует только один источник правды, и все изменения отражаются в одном и том же хранилище:
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();
}
другое решение - форвард свойства свойств
Вот пример моего решения кода, таким образом вам нужно только 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);