关于mobx:store变化了而页面取不到值new两个store实例

这篇文章讲一讲平时应用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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理