Reputation: 2509
I want to implement a reactive design pattern to my react components. Therefore I use mobX but my core setup does not quite work as expected. My setup is to have a rootstore and instatiate all sub-store in it. At the end I want to inject only needed sub-stores within my react components.
export default class UIStore {
@observable language = {};
constructor() {
autorun(() => {console.log(this.language)})
}
@action
async getLanguage() {
const response = await new Promise((resolve) =>
setTimeout(() => resolve({ language: 'en_GB' }), 1500)
);
runInAction(() => this.language = response);
}
}
// Inject all stores in this root store
class RootStore {
constructor() {
this.uiStore = new UIStore(this);
}
}
const rootStore = new RootStore();
export default rootStore;
const Root = () => (
<MobXProvider rootStore={rootStore}>
<App webSocketClient={GlobalWSC}/>
</MobXProvider>
);
ReactDOM.render(<Root/>, document.getElementById('app'));
@inject(stores => ({
uiStore: stores.uiStore // <== this does not work only: stores.rootStore.uiStore
})
)
@observer
class App extends React.Component {
...
componentDidMount() {
console.log(this.props);
this.props.uiStore.getLanguage(); //throws error cannot find function getLanguage()
}
}
}
As you can see from the comment in App.jsx injecting the sub-store only works with stores.rootStore.uiStore
, but why?
Upvotes: 1
Views: 1036
Reputation: 5524
Thats because you've defined it like that in your MobXProvider
In order to have desired behaviour define it like this
const Root = () => (
<MobXProvider uiStore={uiStore}>
<App webSocketClient={GlobalWSC}/>
</MobXProvider>
);
Of course this is not good aproach since you'll have more stores within your root store so you'll have to somehow destruct your root store inner stores as MobXProvider
props. Though I'm not sure why is that causing you problems (I've been using your syntax on multiple projects).
One of ways you could do this
class RootStore {
constructor() {
this.stores = {
uiStore: new UIStore(this)
}
}
}
const Root = () => (
<MobXProvider {...rootStore.stores}>
<App webSocketClient={GlobalWSC}/>
</MobXProvider>
);
Upvotes: 1