Redux configureStore配置自定义middleware报next is not a function错误
问题描述
使用Redux搭配configureStore进行状态配置时,添加自定义中间件遇到报错,初始实现代码如下:
const reducer = { layout: layout, login: login, companies: companies, services: services, platforms: platforms, report: report, users: users, stats: stats, version: version, } const logger = store => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result } const store = configureStore({ reducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger()) });
运行代码后抛出错误:Uncaught TypeError: next is not a function,当前项目使用的依赖版本如下:
"react-redux": "^8.0.2", "redux": "^4.2.0", "redux-thunk": "^2.4.1",
更新 #1
按照相关提示修改代码后出现ESLint报错,修改后的代码如下:
const reducer = { layout: layout, login: login, companies: companies, services: services, platforms: platforms, report: report, users: users, stats: stats, version: version, wizard: wizard, } const logger = store => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result } const middlewareLogger = logger(store)(next)(action); const store = configureStore({ reducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middlewareLogger()) }); export default store;
ESLint报错信息:
src/reducers/index.js Line 33:40: 'next' is not defined no-undef Line 33:46: 'action' is not defined no-undef
错误原因
两次写法的核心问题都是手动执行了中间件函数,破坏了Redux的中间件加载逻辑:
- 初始写法中
concat(logger())手动执行了logger的第一层函数,但没有传入Redux初始化时才会注入的中间件API对象,导致后续Redux加载中间件时参数错位,内部拿到的next实际是对象而非函数,触发类型错误。 - 更新后的写法提前执行
logger(store)(next)(action)完全不符合规范:next和action是Redux中间件运行时才会生成的参数,在store初始化阶段根本不存在,自然触发未定义的ESLint报错。
正确配置方式
Redux中间件是标准的三层柯里化函数,只需要把未执行的中间件函数本身传入中间件队列即可,Redux会在初始化store时按流程自动注入store、next、action参数,不需要手动加括号调用。
正确代码示例:
const reducer = { layout: layout, login: login, companies: companies, services: services, platforms: platforms, report: report, users: users, stats: stats, version: version, wizard: wizard, } // 定义符合规范的logger中间件,不需要提前手动调用 const logger = store => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result } const store = configureStore({ reducer, // 直接传入logger函数本身,不要加()执行 middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger) }); export default store;
如果需要配置多个自定义中间件,直接在concat方法中按执行顺序传入即可,例如.concat(logger, anotherCustomMiddleware)。
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

