redux工具包+使用combineSlices进行RTK查询动态切片注入

问题描述 投票:0回答:1

我们正在 React + Redux Toolkit + RTK Query + Webpack Module Federation + Nx 堆栈上创建一个应用程序。这个想法是将大型应用程序拆分为模块,创建一个全局存储并在模块延迟加载时用减速器填充它。

问题是加载模块时,切片没有添加到rootReucer中。

文件夹结构:

应用程序/
|--外壳/
|--退款/
库/
|--商店/
|--授权/

库/商店

这是一个全局存储,假设应用程序启动时它将是空的。

export interface LazyLoadedSlices {}

export const rootReducer =
  combineSlices(staticSlice).withLazyLoadedSlices<LazyLoadedSlices>();

export const dynamicMiddleware = createDynamicMiddleware();

export const store = configureStore({
  devTools: process.env.ENV !== 'production',
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({ serializableCheck: false }).concat([
      dynamicMiddleware.middleware,
    ]),
});

库/授权

import { rootReducer } from '@core-backoffice/store';


export const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    addTokens: (state, { payload }: PayloadAction<PayloadLogin>) => {
      const { token, refresh } = payload;
      state.token = token;
      state.refresh = refresh;
    },
    addUserData: (state, { payload }: PayloadAction<IUser>) => {
      const { email, fullName, roles, userId, workspaces } = payload;
      state.email = email;
      state.fullName = fullName;
      state.roles = roles;
      state.userId = userId;
      state.workspaces = workspaces;
    },
    logout: () => initialState,
  },
  selectors: {
    selectToken: (state) => state.token,
    selectRefreshToken: (state) => state.refresh,
  },
});

declare module '@core-backoffice/store' {
  export interface LazyLoadedSlices extends WithSlice<typeof authSlice> {}
}

const injectedSlice = authSlice.injectInto(rootReducer);

export const { addTokens, logout, addUserData } = injectedSlice.actions;
export const { selectRefreshToken, selectToken } = injectedSlice.selectors;

应用程序/外壳

useDispatch、useSelector 和 authApi 用于 useAuth 和 useCheckAuth 钩子

export function App() {
  useCheckAuth();

  const location = useLocation();
  const rootPath = useRootPath('/');

  const token = useAppSelector((store) => store.auth?.token);

  const { logout } = useAuth();

  return (
    <React.Suspense fallback={null}>
      <Routes>
        <Route path="/" element={<NxWelcome title="shell" />} />
        <Route path="/moneyback/*" element={<MoneybackApp />} />
        <Route path="/login" element={<LoginPage />} />
      </Routes>
    </React.Suspense>
  );
}

export default App;

应用程序/退款/切片

apps/moneyback/app.tsx
还使用useDispatch、useSelector和servicesApi挂钩,还使用useAuth和useCheckAuth

import { rootReducer } from '@core-backoffice/store';
import { createSlice, WithSlice } from '@reduxjs/toolkit';

const initialState: { services: string[] } = {
  services: [],
};

export const servicesSlice = createSlice({
  name: 'servicesSlice',
  initialState,
  reducers: {
    addService: (state) => {
      state.services = [String(Math.random())];
    },
  },
  selectors: {
    selectServices: (state) => state.services,
  },
});

declare module '@core-backoffice/store' {
  export interface LazyLoadedSlices extends WithSlice<typeof servicesSlice> {}
}

const injectedSlice = servicesSlice.injectInto(rootReducer);
export const { addService } = injectedSlice.actions;
export const { selectServices } = injectedSlice.selectors;

(图片)全球商店中的authSlice

启动应用程序后,authSlcie 和 authApi 已添加到商店。

图中

(image)可以看到调用了dispatch(addServices),但是store中没有切片

所有代码都是根据文档编写的 redux 工具包代码拆分

我预计切换到loclhost/moneyback后,moneyback模块将被延迟加载,并且servicesApi和servicesSlice将被添加到商店中。然而,这并没有发生。

reactjs redux redux-toolkit rtk-query webpack-module-federation
1个回答
0
投票

如果您的捆绑程序以某种方式将

libs/store
捆绑在不同的捆绑包中两次,则可能会发生这种情况。

如果发生这种情况,您可以通过执行类似的操作来解决这个问题

window[Symbol.for("ReduxStore")] = window[Symbol.for("ReduxStore")] || configureStore(...)

export const store = window[Symbol.for("ReduxStore")]

在你的

libs/store

© www.soinside.com 2019 - 2024. All rights reserved.