Mobx-react中@inject装饰器如何将Store名称映射至实际实例?
关于Mobx-react中@inject映射Store实例的原理
这个问题问得很到位!其实@inject能把指定的Store名称映射到实际实例,核心是靠React Context和**高阶组件(HOC)**的配合,一步步拆解给你看:
第一步:上层Provider的铺垫
要让@inject生效,必须在组件树的上层用<Provider>组件把你的Store实例“注入”到全局可访问的Context中。比如你会这么写:import { Provider } from 'mobx-react'; import myStore from './stores/myStore'; ReactDOM.render( <Provider store={myStore}> <Abc /> </Provider>, document.getElementById('root') );这里的Provider本质是一个Context Provider组件,它会把你传入的所有Store(比如这里的
myStore)以键值对的形式存在Context里,键就是你传给Provider的属性名(也就是store)。第二步:@inject作为高阶组件的作用
@inject('store')是一个装饰器,它会把你的Abc组件包裹成一个新的高阶组件。这个HOC会做两件关键的事:- 订阅Provider提供的Context,从中取出键为
store的那个值(也就是之前传入的myStore实例); - 把这个Store实例作为
store属性,传递给被包裹的Abc组件,所以你就能通过this.props.store拿到它了。
- 订阅Provider提供的Context,从中取出键为
进阶:多Store注入与自定义映射
如果你需要注入多个Store,直接在@inject里传多个名称就行:@inject('userStore', 'cartStore') @observer class Abc extends React.Component { // 可以通过this.props.userStore和this.props.cartStore访问对应实例 }另外,@inject还支持传入一个函数,让你自定义Context到props的映射:
@inject(allStores => ({ user: allStores.userStore, cart: allStores.cartStore })) @observer class Abc extends React.Component { // 现在可以通过this.props.user和this.props.cart访问 }这个函数会接收Context里的所有Store作为参数,你可以按需挑选、重命名或者组合后传给组件。
和@observer的配合(额外补充)
虽然你问的是@inject的原理,但提一句:@observer是让组件响应Store的状态变化,当Store里的可观察值改变时,组件会自动重新渲染,这俩通常一起用才能发挥Mobx的威力~
内容的提问来源于stack exchange,提问作者darKnight
相关产品推荐
相关产品推荐

