从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
相关产品推荐
相关产品推荐

