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

8次阅读

共计 1882 个字符,预计需要花费 5 分钟才能阅读完成。

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

正文完
 0