You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Redux createStore迁移至configureStore时添加enhancers引发运行时错误

Redux从createStore转configureStore后运行报错:Expected the reducer to be a function

受VS Code提示启发,尝试将现有Redux代码从createStore改写为configureStore,目前使用单个reducer管理整个状态,暂未使用combineReducers。

重构前代码

declare module "@mui/styles/defaultTheme" {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}
const composeEnhancers = process.env.NODE_ENV === "production" ? compose : composeWithDevTools({});
export const store = createStore(reducer, composeEnhancers(applyMiddleware(thunkMiddleware)));
const AppProvider: FC = ({ children }) => {
  return (
    <Provider store={store}>
      <QueryClientProvider client={useQueryClient()}>
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>
            <SnackbarProvider
              maxSnack={3}
              anchorOrigin={{
                vertical: "bottom",
                horizontal: "center",
              }}
            >
              <PlaceContextProvider>
                <CheckSupportForLocalStorage>
                  <CheckSupportForGeolocation>
                    <SetBackground>
                      <Router>{children}</Router>
                    </SetBackground>
                  </CheckSupportForGeolocation>
                </CheckSupportForLocalStorage>
              </PlaceContextProvider>
            </SnackbarProvider>
          </ThemeProvider>
        </StyledEngineProvider>
      </QueryClientProvider>
    </Provider>
  );
};

重构后代码(编译通过但运行报错)

declare module "@mui/styles/defaultTheme" {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}
const composeEnhancers = process.env.NODE_ENV === "production" ? compose : composeWithDevTools({});
export const store = configureStore({ reducer, enhancers:[composeEnhancers] });
const AppProvider: FC = ({ children }) => {
  return (
    <Provider store={store}>
      <QueryClientProvider client={useQueryClient()}>
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>
            <SnackbarProvider
              maxSnack={3}
              anchorOrigin={{
                vertical: "bottom",
                horizontal: "center",
              }}
            >
              <PlaceContextProvider>
                <CheckSupportForLocalStorage>
                  <CheckSupportForGeolocation>
                    <SetBackground>
                      <Router>{children}</Router>
                    </SetBackground>
                  </CheckSupportForGeolocation>
                </CheckSupportForLocalStorage>
              </PlaceContextProvider>
            </SnackbarProvider>
          </ThemeProvider>
        </StyledEngineProvider>
      </QueryClientProvider>
    </Provider>
  );
};

运行时错误信息

Uncaught Error: Expected the reducer to be a function

问题分析与解决方案

问题出在enhancers的使用方式上:

  • 你直接把composeEnhancers放进数组,但configureStore的enhancers参数接受的是函数数组,每个元素是 enhancer 本身,而不是已经执行过compose后的结果。
  • 更重要的是,Redux Toolkit的configureStore已经默认集成了Redux DevTools和thunk中间件,完全不需要手动调用composeWithDevTools和applyMiddleware。

推荐写法:利用RTK默认配置

直接省略手动的enhancers配置,RTK会自动处理所有通用需求:

export const store = configureStore({ reducer });
  • 开发环境自动启用DevTools,生产环境自动关闭
  • thunk中间件默认已包含在默认中间件集合中

自定义配置写法(仅当有特殊需求时使用)

如果确实需要手动组合enhancers,应该用函数形式的enhancers参数,获取默认enhancers后再组合:

export const store = configureStore({
  reducer,
  enhancers: (defaultEnhancers) => {
    return composeEnhancers(...defaultEnhancers, applyMiddleware(thunkMiddleware));
  }
});

另外,若要自定义中间件,应该通过middleware参数配置,而非enhancers:

export const store = configureStore({
  reducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(thunkMiddleware)
});

不过thunk已经是默认中间件的一部分,这一步通常可以省略。

总结:你的错误是因为将执行过的compose结果当作enhancer函数传入数组,导致RTK内部处理时出现reducer类型错误。使用RTK的默认配置即可解决问题,无需手动处理enhancers和中间件。

内容的提问来源于stack exchange,提问作者Kiszuriwalilibori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:27:44