une*_*et7 5 state-management reactjs mobx mobx-react
如Mobx 文档中的建议,我以以下方式创建了多个商店:
class bankAccountStore {
constructor(rootStore){
this.rootStore = rootStore;
}
...
class authStore {
constructor(rootStore){
this.rootStore = rootStore;
}
...
Run Code Online (Sandbox Code Playgroud)
最后以以下方式创建根存储。另外,我更喜欢在master商店构造函数中构造子商店。此外,我发现有时我的子存储必须观察父存储的一些数据,因此我将其传递给子构造函数
class RootStore {
constructor() {
this.bankAccountStore = new bankAccountStore(this);
this.authStore = new authStore(this);
}
}
Run Code Online (Sandbox Code Playgroud)
通过以下方式提供给应用:
<Provider rootStore={new RootStore()}>
<App />
</Provider>
Run Code Online (Sandbox Code Playgroud)
然后像这样注入组件:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
即使它需要一部分根存储,是否仍是将根存储每次注入组件的正确有效的方法?如果不是,如何将auth Store注入用户组件?
编辑:我已经做出了结束github讨论的答案。答案中提供的讨论链接
une*_*et7 16
这个答案可能是自以为是,但它可能会间接帮助社区。
经过大量研究,我看到许多人在实践中使用了以下方法。一般方法 有一个根存储,可以作为存储之间的通信通道。
问题一:如何组织stores并注入到组件中?
方法一:
应用程序.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>
Run Code Online (Sandbox Code Playgroud)
组件.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
}
Run Code Online (Sandbox Code Playgroud)
方法二:
应用程序.js
class RootStore {
constructor() {
this.userStore = new UserStore(this);
this.authStore = new AuthStore(this);
}
}
const rootStore = new RootStore()
<Provider rootStore={rootStore}>
<App />
</Provider>
Run Code Online (Sandbox Code Playgroud)
组件.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
}
Run Code Online (Sandbox Code Playgroud)
除了语法差异之外,方法 1 和方法 2 没有任何区别。好的!那是注射部分!
问题二:如何进行店间沟通?(尽量避免)
现在我知道一个好的设计可以让商店保持独立,减少耦合。但是以某种方式考虑一种情况,
UserStore
如果更改了某个变量,我希望变量 in发生AuthStore
变化。使用Computed
. 这种方法对于上述两种方法都是通用的授权商店.js
export class AuthStore {
constructor(rootStore) {
this.rootStore = rootStore
@computed get dependentVariable() {
return this.rootStore.userStore.changeableUserVariable;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这对社区有所帮助。更详细的讨论可以参考我在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>
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以精确地访问所需的商店,因为大多数商店都覆盖一个域实例。不过,两个子商店都可以与进行通信rootStore
。设置其属性或对其调用方法。
如果您不需要跨商店通信-您可能根本不需要rootStore
。删除它,不要传递给其他商店。只需保留2家兄弟姐妹商店
回答关于不注入整个商店的问题,您可能会受益于mapperFunction
(例如mapStateToProps
在redux中)文档
@inject(stores => ({
someProp: stores.rootStore.someProp
})
)
@observer
class User extends React.Component {
// no props.rootStore here, only props.someProp
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3725 次 |
最近记录: |