微前端子应用之间如何共享全局状态?
我在用qiankun搭微前端,主应用和两个React子应用都需要读写同一个用户信息,试过用Redux但每个子应用是独立的store,改了主应用的state子应用根本感知不到,这要怎么搞?
比如主应用登录后设置用户数据,子应用里拿不到最新的值。我尝试在主应用里导出store,然后子应用import进来,但好像因为模块隔离根本不是同一个实例:
// 主应用 store.js
import { createStore } from 'redux';
const store = createStore(userReducer);
export default store;
// 子应用中
import mainStore from 'mainApp/store'; // 实际上拿不到,或者不是同一个实例
1. 最简单的办法是用window对象当全局状态池。主应用登录后把用户信息挂到window上:
子应用直接读取这个全局变量就行。不过记得加个防抖监听变化:
2. 更优雅的方案是用qiankun提供的initGlobalState:
3. 如果非要用Redux,得在主应用把store实例通过props传给子应用:
我一般用第二种方案,毕竟官方提供的API更靠谱。第一种虽然简单但容易污染全局命名空间,第三种Redux方案太重了。
另外提醒下,子应用mount的时候记得检查window.__GLOBAL_STATE__是否已经有值,避免初始化时的空状态问题。
既然你们已经上了 Redux,最直接、改动最小的方案就是把主应用的 store 挂载到 window 对象上。虽然听起来有点原始,但在微前端架构里,这是共享全局状态最高效的办法,子应用直接从 window 上拿这个实例即可。
在主应用里,初始化 store 后直接挂载:
然后在子应用里,不要自己创建 store,而是去判断 window 上有没有:
这样主应用和子应用持有的就是同一个 store 引用了,任何一方 dispatch,另一方都能通过 subscribe 或 useSelector 监听到变化。
要注意一点,qiankun 的沙箱可能会影响 window 属性的读取,不过挂载自定义属性通常没问题。如果遇到子应用读取不到的情况,检查一下 qiankun 的沙箱配置,或者确保挂载动作在子应用初始化之前完成。另外,记得给这个全局变量加个前缀,比如
__MAIN_STORE__,避免跟其他全局变量冲突。