As suggested here in the Mobx documentation I have created multiple stores in the following manner:
class bankAccountStore {
constructor(rootStore){
this.rootStore = rootStore;
}
...
class authStore {
constructor(rootStore){
this.rootStore = rootStore;
}
...
And finally creating a root store in the following manner. Also I prefer to construct children stores within master's store constructor. Moreover, I found that sometimes my child store has to observe some data from parent store, so I pass this into child constructors
class RootStore {
constructor() {
this.bankAccountStore = new bankAccountStore(this);
this.authStore = new authStore(this);
}
}
Providing to the App in following manner:
<Provider rootStore={new RootStore()}>
<App />
</Provider>
And injecting to the component in like this:
@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;
}
}
Is it the correct and efficient way to inject the root store everytime to the component even if it needs a part of the root store? If not how to inject auth Store to the user component?
EDIT: I have made an answer concluding the github discussion. Link of the discussion provided in the answer
Create a new React app We can use cd mobx-react to go into the folder. Now, inside of the src folder, we can create a folder for our components, create a PetList component inside the folder, and open the file in your favorite editor.
My understanding is I that with observer , a change in all accessed observables in the last render will cause a re-render, even if the observable is nested deep in the data store, while inject only re-renders when observables accessed in the injector function change.
In this tutorial, we will learn how to use MobX with React Functional Components. MobX being a very useful state management library reduces the code that needs to be written for global state management. Mobx is easy to use and quick to learn.
This answer may be opinionated but it may help the community indirectly.
After a lot of research, I saw below approaches used in practice by many. General methods Have a root store that can act as a communication channel between stores.
Question 1: How to organise stores and inject them into the component?
Approach 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
}
Approach 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
}
Approach 1 and Approach 2 doesn't make any difference other than syntax difference. Okay! that is the injection part!
Question 2: How to have an inter-store communication? (Try to avoid it)
Now I know a good design keeps stores independent and less coupled. But somehow consider a scenario where I want the variable in
UserStore
to change if a certain variable inAuthStore
is changed. UseComputed
. This approach is common for both the above approachesAuthStore.js
export class AuthStore {
constructor(rootStore) {
this.rootStore = rootStore
@computed get dependentVariable() {
return this.rootStore.userStore.changeableUserVariable;
}
}
}
I hope this helps the community. For more detailed discussion you can refer to the issue raised by me on Github
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With