使用mobx创建多个商店并将其注入组件的正确方法 - ReactJs

问题描述 投票:5回答:2

正如在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的讨论。答案中提供的讨论链接

reactjs mobx mobx-react state-management
2个回答
3
投票

我建议你有多家商店,以避免连锁商店。正如我们在申请中所做的那样:

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(如还原中的mapStateToPropsdocs here

@inject(stores => ({
        someProp: stores.rootStore.someProp
    })
)
@observer
class User extends React.Component {
// no props.rootStore here, only props.someProp

}

2
投票

这个答案可能是固执己见的,但它可能间接地帮助社区。 经过大量的研究,我看到了许多人在实践中使用的方法。常规方法具有可作为商店之间的通信通道的根存储。

问题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

© www.soinside.com 2019 - 2024. All rights reserved.