正如在Mobx documentation中所建议的那样,我以下列方式创建了多个商店:
class bankAccountStore {
constructor(rootStore){
this.rootStore = rootStore;
}
...
class authStore {
constructor(rootStore){
this.rootStore = rootStore;
}
...
最后以下面的方式创建根存储。还有I prefer在master的商店构造函数中构建子库。此外,我发现有时我的子商店必须从父商店观察一些数据,所以我把它传递给子构造函数
class RootStore {
constructor() {
this.bankAccountStore = new bankAccountStore(this);
this.authStore = new authStore(this);
}
}
以下列方式提供给应用程序:
<Provider rootStore={new RootStore()}>
<App />
</Provider>
并像这样注入组件:
@inject('rootStore')
@observer
class User extends React.Component{
constructor(props) {
super(props);
//Accessing the individual store with the help of root store
this.authStore = this.props.rootStore.authStore;
}
}
是否是每次向组件注入根存储的正确而有效的方法,即使它需要根存储的一部分?如果不是如何将auth Store注入用户组件?
编辑:我已经回答了github的讨论。答案中提供的讨论链接
我建议你有多家商店,以避免连锁商店。正如我们在申请中所做的那样:
class RootStore {
@observable somePropUsedInOtherStores = 'hello';
}
class AuthStore {
@observeble user = 'Viktor' ;
constructor(rootStore) {
this.rootStore = rootStore;
}
// this will reevaluate based on this.rootStore.somePropUsedInOtherStores cahnge
@computed get greeting() {
return `${this.rootStore.somePropUsedInOtherStores} ${this.user}`
}
}
const rootStore = new RootStore();
const stores = {
rootStore,
bankAccountStore: new BankAccountStore(rootStore),
authStore = new AuthStore(rootStore)
}
<Provider {...stores}>
<App />
</Provider>
通过这种方式,您可以准确访问所需的商店,因为大多数商店只涵盖一个域实例。尽管如此,这两个子商店都能够与rootStore
进行沟通。在其上设置其属性或调用方法。
如果您不需要跨店通信 - 您可能根本不需要rootStore
。删除它,不要传递到其他商店。只需保留2个兄弟姐妹商店
回答关于注入不是整个商店的问题,你可能会受益于mapperFunction
(如还原中的mapStateToProps
)docs here
@inject(stores => ({
someProp: stores.rootStore.someProp
})
)
@observer
class User extends React.Component {
// no props.rootStore here, only props.someProp
}
这个答案可能是固执己见的,但它可能间接地帮助社区。 经过大量的研究,我看到了许多人在实践中使用的方法。常规方法具有可作为商店之间的通信通道的根存储。
问题1:如何组织商店并将其注入组件?
方法1:
App.js
// Root Store Declaration
class RootStore {
constructor() {
this.userStore = new UserStore(this);
this.authStore = new AuthStore(this);
}
}
const rootStore = new RootStore()
// Provide the store to the children
<Provider
rootStore={rootStore}
userStore={rootStore.userStore}
authStore={rootStore.authStore}
>
<App />
</Provider>
Component.js
// Injecting into the component and using it as shown below
@inject('authStore', 'userStore')
@observer
class User extends React.Component {
// only this.props.userStore.userVariable
}
方法2:
App.js
class RootStore {
constructor() {
this.userStore = new UserStore(this);
this.authStore = new AuthStore(this);
}
}
const rootStore = new RootStore()
<Provider rootStore={rootStore}>
<App />
</Provider>
Component.js
// Injecting into the component and using it as shown below
@inject(stores => ({
userStore: stores.userStore,
authStore: stores.authStore,
})
)
@observer
class User extends React.Component {
// no this.props.rootStore.userStore,userVariable here,
// only this.props.userStore.userVariable
}
方法1和方法2除了语法差异之外没有任何区别。好的!那是注射部分!
问题2:如何进行店内沟通? (尽量避免它)
现在我知道一个好的设计可以保持商店的独立性和耦合性。但不知何故,如果
UserStore
中的某个变量发生变化,我会想要改变AuthStore
中的变量。使用Computed
。这种方法对于上述两种方法都是常见的AuthStore.js
export class AuthStore {
constructor(rootStore) {
this.rootStore = rootStore
@computed get dependentVariable() {
return this.rootStore.userStore.changeableUserVariable;
}
}
}
我希望这有助于社区。有关更详细的讨论,请参阅issue raised by me on Github