如何在NextJs Middleware中访问Redux Store并解决相关报错?
问题原因与解决方案
报错原因
- 第一个报错
TypeError: result.response.headers is not iterable:next-redux-wrapper提供的getServerSideProps方法是专门为页面的getServerSideProps生命周期设计的,要求返回包含props字段的对象,你直接返回NextResponse对象不符合它的预期返回结构,导致解析头信息时报错。 - 第二个报错
eval not allowed in Middleware:NextJs的Middleware运行在Edge Runtime环境,禁止使用evalAPI,你之前的代码引入了redux-devtools-extension和React开发环境依赖包,这类包底层用到了eval,触发了运行限制。
修复方案
步骤1:调整store初始化逻辑
拆分store的通用初始化逻辑,导出独立的初始化方法,同时对开发工具做环境判断,避免在Middleware运行时引入含eval的依赖:
// store.js修改后代码 import { createStore, applyMiddleware } from 'redux'; // 用developmentOnly版本,生产环境自动剔除 import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly'; import { HYDRATE, createWrapper } from 'next-redux-wrapper'; import rootReducer from './reducers/rootReducer'; import createSagaMiddleware from 'redux-saga'; import rootSaga from './sagas/rootSaga'; const sagaMiddleware = createSagaMiddleware(); const reducer = (state, action) => { if (action.type === HYDRATE) { const nextState = { ...state, tick: { ...action.payload.tick, }, }; return nextState; } else { return rootReducer(state, action); } }; // 导出独立初始化方法,供Middleware直接调用 export const initStore = (preloadedState = {}) => { let middleware = applyMiddleware(sagaMiddleware); // 仅在客户端开发环境加载Redux开发工具 if (process.env.NODE_ENV === 'development' && typeof window !== 'undefined') { middleware = composeWithDevTools(middleware); } const store = createStore(reducer, preloadedState, middleware); sagaMiddleware.run(rootSaga); return store; }; export const nextStore = createWrapper(initStore);
步骤2:重写Middleware逻辑
不要用getServerSideProps包裹Middleware,直接调用独立的初始化方法创建单次请求隔离的store:
// middleware修改后代码 import { NextResponse } from 'next/server'; import { initStore } from '@store/store'; const middleware = async (req, ev) => { // 为当前请求单独初始化store,无状态污染 const store = initStore(); const { tick } = store.getState(); console.log(tick); // 若需要将状态同步给后续页面逻辑,可序列化后存入请求头 const response = NextResponse.next(); response.headers.set('x-redux-preload-state', JSON.stringify(store.getState())); return response; }; export default middleware;
注意事项
- Edge Runtime支持的API有限,若你的reducer或saga中用到了仅Node.js/浏览器支持的API,需要额外做兼容处理。
- 页面的
getServerSideProps中可以读取x-redux-preload-state请求头的内容作为预加载状态初始化store,避免重复执行业务逻辑。
内容的提问来源于stack exchange,提问作者Robdll
相关产品推荐
相关产品推荐

