这篇文章讲一讲平时使用mobx
时常遇到的一种store
变化了而页面取不到值的场景——new
了两个store
实例
假设现在有一个storeA
,里面存放了一个属性a
,在组件A
挂载完成时调接口获取数据并赋给属性a
。现在有另外一个组件B
也需要用到属性a
,组件B
先再次生成一份storeA
并通过Provide
注入,然后在里头获取属性a
,发现获取不到。
这是因为组件A
依赖的storeA
实例与组件B
依赖的storeA
实例并不是同一个引用,每次new
都会生成一个新的store
实例,store
的使用遵循就近原则。
下面举个例子说明:
全局store
import UserInfoStore from "./UserInfoStore";
export default {
userInfoStore: new UserInfoStore()
}
注入全局store
ReactDOM.render(
<HashRouter>
<Provider {...stores}>
{renderRoutes(routes)}
</Provider>
</HashRouter>,
document.getElementById('root')
)
Layout
组件中获取用户信息存放到全局的UserInfoStore
中
interface IProps extends RouteConfigComponentProps<void> {
userInfoStore?: UserInfoStore
}
const Layout = (props: IProps) => {
const {route, userInfoStore} = props
const { fetchUserInfo } = userInfoStore as UserInfoStore;
useEffect(() => {
/** 获取用户信息 */
fetchUserInfo();
})
return (
<div className={styles.layout}>
<div className={styles.header}>topbar</div>
<div className={styles.menu}>slider</div>
<div className={styles.content}>
{renderRoutes(route?.routes)}
</div>
<div className={styles.footer}>footer</div>
</div>
)
}
export default inject('userInfoStore')(observer(Layout));
现在页面组件Page
再次生成新的UserInfoStore
并通过Provider
注入
// 页面组件Page依赖的store
import PageStore from "./PageStore";
import UserInfoStore from "../../../store/UserInfoStore";
export default {
pageStore: new PageStore(),
userInfoStore: new UserInfoStore(), // 生成新的store实例
}
页面组件Page
注入store
const Page = (props: Iprops) => {
return <Provider {...stores}>
<Main {...props}></Main>
</Provider>
}
export default Page;
interface IProps extends RouteConfigComponentProps<void> {
mainStore?: MainStore;
userInfoStore?: UserInfoStore;
}
const Main = (props: IProps) => {
const { mainStore, userInfoStore } = props;
// 这里取到的是Page组件注入的userInfoStore实例,而不是全局store中的userInfoStore实例,因此获取不到用户信息
const { userInfo } = userInfoStore as UserInfoStore;
useEffect(() => {
console.log('userInfo', userInfo)
})
return (
<div>Main</div>
)
}
export default inject('mainStore', 'userInfoStore')(observer(Main));
解决方法时Page
组件不同另外再次生成userInfoStore
,直接使用全局的userInfoStore
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。