NextJS服务端渲染(SSR)中如何获取Redux Store?
问题分析与解决方案
你遇到的核心问题是在_app.tsx中手动创建了Redux Store,完全绕过了next-redux-wrapper的自动注入逻辑,导致getInitialProps的ctx对象里找不到store。下面一步步帮你修复:
1. 移除_app.tsx中手动创建的Store和Persistor
你的MyApp组件里自己调用createStore(persistedReducer)和persistStore(store),这和next-redux-wrapper的设计完全冲突——它本来就会帮你在服务端和客户端自动创建并注入Store实例。把这段冗余代码删掉:
// 删掉这两行! const store = createStore(persistedReducer); const persistor = persistStore(store);
2. 正确获取next-redux-wrapper注入的Store并配置PersistGate
wrapper.withRedux已经把创建好的Store通过props传给了MyApp,我们只需要在客户端初始化持久化(服务端不需要persistStore)。修改MyApp组件如下:
function MyApp({ Component, pageProps, store }) { const Layout = Component.layout || (({ children }) => <> {children} </>); // 仅在客户端初始化persistor const [persistor, setPersistor] = React.useState(null); React.useEffect(() => { if (typeof window !== 'undefined') { // 客户端环境才创建持久化实例 const persistorInstance = persistStore(store); setPersistor(persistorInstance); } }, [store]); // 服务端渲染时直接返回内容,不需要等待PersistGate if (typeof window === 'undefined' || !persistor) { return ( <React.Fragment> <Head> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <title>Coala Admin</title> </Head> <Layout> <Component {...pageProps} /> </Layout> </React.Fragment> ); } // 客户端渲染时用PersistGate包裹应用 return ( <PersistGate persistor={persistor}> <React.Fragment> <Head> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <title>Coala Admin</title> </Head> <Layout> <Component {...pageProps} /> </Layout> </React.Fragment> </PersistGate> ); }
3. 现在getInitialProps能正常拿到Store了
wrapper.withRedux已经把Store注入到ctx对象里,你可以直接访问:
MyApp.getInitialProps = async ({ Component, ctx }: AppContext): Promise<AppInitialProps> => { console.log(ctx.store); // 现在能正常打印Store实例了! let pageProps = {}; if (Component.getInitialProps) { pageProps = await Component.getInitialProps(ctx); } return { pageProps }; };
额外验证:store/index.ts的配置没问题
你的makeStore函数逻辑是对的——服务端返回普通Store,客户端返回包含persistor的扩展Store对象,next-redux-wrapper能正确识别并处理这种结构。
为什么之前找不到Store?
next-redux-wrapper的withRedux高阶组件会在应用启动时自动创建Store,并把它注入到AppContext的ctx中。但你手动创建了新的Store,相当于覆盖了wrapper的注入逻辑,导致ctx里的Store丢失。
内容的提问来源于stack exchange,提问作者a_lady_on_fire




