我想为我的React组件实现一个反应式设计模式。因此,我使用mobX,但是我的核心设置无法按预期工作。 我的设置是拥有一个根存储并将其中的所有子存储实例化。 最后,我只想在我的react组件中注入所需的子商店。
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()
}
}
}
从App.jsx的注释中可以看到,注入子商店仅适用于stores.rootStore.uiStore
,但是为什么?
答案 0 :(得分:1)
那是因为您已经在MobXProvider
为了具有期望的行为,请像这样定义它
const Root = () => (
<MobXProvider uiStore={uiStore}>
<App webSocketClient={GlobalWSC}/>
</MobXProvider>
);
当然,这不是一个好方法,因为您在根存储中将拥有更多存储,因此您必须以某种方式破坏根存储内部存储作为MobXProvider
道具。尽管我不确定为什么会导致您出现问题(我一直在多个项目中使用您的语法)。
您可以执行此操作的一种方式
class RootStore {
constructor() {
this.stores = {
uiStore: new UIStore(this)
}
}
}
const Root = () => (
<MobXProvider {...rootStore.stores}>
<App webSocketClient={GlobalWSC}/>
</MobXProvider>
);