如何同步到商店实例的反应?

时间:2018-05-07 15:38:38

标签: reactjs react-redux mobx mobx-react

我有一个包含@observable名称categories = []的商店! 现在我想将此商店导入其他3家商店,但我希望在其中两家商店同步categories。就像categories在一个商店中更改一样,它也适用于另一个商店。最好的方法是什么?

我添加了一个我想要的样本,但它只是一个protptype所以请不要介意语法问题,我试图理解在商店之间同步属性的正确方法。

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 :(得分:2)

这就是我如何处理这个问题。

我的解决方案还可以扩展到每个商店的所有未来属性。  商店1和商店2共享一个类别列表,商店3有一个单独的列表。

std::string::operator[]()

根据需要创建3个商店,并引用根商店

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

创建包含类别数组的类别商店。

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

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

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

Root Store,包含类别列表和所有3个商店。

class CategoricalStore {
  @observable categories = [];

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

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; 是如何更新两个商店的。

我也继续前进并提供了在React中编写的CodeSandbox示例。

答案 1 :(得分:1)

您已经更新了答案,现在我已经理解了您想要做的事情。可能我会做这样的事情:

<强> 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;
}

使用以下代码,您将从Store1导出的mobx导入现有实例,如果需要,可以let newStore = new Categories();创建新实例。

** 用户编辑前的旧答案 **

如果categories已经是可观察的,那么您不必担心这一点。

您应该从@computed创建categories属性获取值。

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

答案 2 :(得分:0)

我同意卢卡斯,但也许我可以使这个例子更简单。

您不只是想分享类别,您想要分享 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();
}

另一种解决方案 - 转发属性属性

这是我的代码解决方案的一个示例,这样您只需要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);