如何在Next.js的getInitialProps中访问Redux的store实例?
解决方案
核心原因
- 你当前使用的
next-redux-wrapperv7+版本默认不会自动将store注入到页面级getInitialProps的上下文中 - React钩子(如
useDispatch)只能在函数组件的顶层调用,getInitialProps是预渲染阶段运行的静态方法,本身就不支持调用任何React钩子 - 你现有代码中直接创建单例store、手动在
_app.js中重复包裹Provider的写法不符合next-redux-wrapper的规范,也会导致上下文不匹配
修复步骤
1. 修正store创建逻辑
不要直接创建单例store,改为导出makeStore工厂函数和统一的wrapper实例,避免服务端渲染状态污染:
// store文件代码 import { applyMiddleware, createStore } from "redux"; import { createWrapper } from "next-redux-wrapper"; import { composeWithDevTools } from "redux-devtools-extension"; import thunk from "redux-thunk"; import rootReducer from "./reducers"; const makeStore = () => { const initialState = {}; const middleware = [thunk]; return createStore( rootReducer, initialState, composeWithDevTools(applyMiddleware(...middleware)) ); }; // 统一创建wrapper并导出 export const wrapper = createWrapper(makeStore); export default makeStore;
2. 修正_app.js代码
移除手动编写的Redux Provider,next-redux-wrapper会自动注入store对应的Provider:
// pages/_app.js代码 import { wrapper } from './store'; import { ThemeProvider } from '你的主题库路径'; import theme from '你的主题配置路径'; function MyApp({ Component, pageProps }) { return ( <ThemeProvider theme={theme}> <Component {...pageProps} /> </ThemeProvider> ); } export default wrapper.withRedux(MyApp);
3. 修正[cid].js的getInitialProps写法
用wrapper.wrapGetInitialProps包裹你的getInitialProps逻辑,即可拿到注入的store实例:
// pages/[cid].js代码 import { useDispatch, useSelector } from 'react-redux'; import { wrapper } from '../store'; // 导入你需要的action方法,比如fetchCourseById export default function Course(props) { // 组件内部仍可正常使用Redux钩子 const dispatch = useDispatch(); const currentCourse = useSelector(state => state.course.current); // 其余组件逻辑 } Course.getInitialProps = wrapper.wrapGetInitialProps(async ({ store, query }) => { const { cid } = query; // 直接通过store实例调用dispatch,不要使用钩子 await store.dispatch(fetchCourseById(cid)); // 可正常返回需要传入组件的属性 return { cid }; });
注意事项
- 所有预渲染阶段对Redux的操作都直接通过注入的
store实例调用store.dispatch、store.getState()即可,不要尝试在getInitialProps/getServerSideProps等方法中使用React钩子 - 必须保证每次调用
makeStore都返回新的store实例,不要用单例store,否则多用户访问时会出现状态串扰的问题
内容的提问来源于stack exchange,提问作者relidon
相关产品推荐
相关产品推荐

