【问题标题】:Generating Redux Toolkit TypeScript types when using preloadedState使用 preloadedState 时生成 Redux Toolkit TypeScript 类型
【发布时间】:2021-09-01 19:07:21
【问题描述】:

我正在尝试设置包含 React 测试库、Redux 工具包、RTK Query 和 TypeScript 的测试环境,但我遇到了无法解决的问题。

我不知道的主要问题是如何在提供preloadedState 时生成AppDispatch 类型as explained in the documentation here

按照 RTK 文档直接使用 configureStore() 没问题,因为商店是在模块内创建的:

const store = configureStore({
  reducer: {
    home: homeReducer,
    [homeApi.reducerPath]: homeApi.reducer,
  },
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
    homeApi.middleware,
  ),
});

export type RootState = ReturnType<typeof store.reducer>;
export type AppDispatch = typeof store.dispatch; // not a problem as store exists here

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

export default store;

但是,这样做会导致难以将 preloadedState 值传递给 configureStore() 并保留生成的类型。如果我提取reducer并使用combineReducers(),我可以从那里生成RootState,但我仍然不知道如何导出AppDispatch,因为store.dispatch在创建商店之前不存在,并且为了要通过preloadedState我需要延迟商店的创建。

export const rootInitialState: Pick<RootState, 'home'> = {
  home: homeInitialState,
};

const reducer = combineReducers({
  home: homeReducer,
  [homeApi.reducerPath]: homeApi.reducer,
});

export type RootState = ReturnType<typeof reducer>;

// this is the problem as store is created externally to this module,
// so how can I extract this type now?
export type AppDispatch = typeof store.dispatch; 

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

export const createStore = (preloadedState: Partial<RootState>) => configureStore({
  reducer,
  preloadedState,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
    homeApi.middleware,
  ),
});

这真的可以做到吗?在这一点上,我完全被难住了,所以如果有人可以提供解决方案或让我摆脱痛苦,我将非常感激。

【问题讨论】:

    标签: typescript redux redux-toolkit


    【解决方案1】:

    很简单,你只需要改变文件中声明的顺序,再增加一层检查。

    关键是虽然我们还没有真正的商店,但我们有createStore,它返回新的商店实例。 TS 可以计算出“这个函数返回的值的类型”,所以我们可以使用它来代替:

    export const createStore = (preloadedState: Partial<RootState>) => configureStore({
      reducer,
      preloadedState,
      middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
        homeApi.middleware,
      ),
    });
    
    // 1) Take the type of `createStore`
    // 2) Figure out the return type of that function, which is a store
    // 3) Look up the type of the `dispatch` field in that returned store type
    export type AppDispatch = ReturnType<typeof createStore>['dispatch'];
    

    【讨论】:

    • 太棒了,非常感谢,这正是我一直在寻找的!
    猜你喜欢
    • 2021-05-24
    • 2021-07-11
    • 2020-09-26
    • 2021-08-23
    • 2022-06-22
    • 1970-01-01
    • 2018-08-31
    • 2022-06-12
    • 2022-01-22
    相关资源
    最近更新 更多