You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS+Redux Persist SSR页面源码不渲染HTML问题求助

问题原因

你的Next.js SSR失效是因为redux-persist的PersistGate组件会在客户端完成持久化数据恢复后才渲染子组件。服务器端渲染时,PersistGate还未完成数据加载,只会输出空的loading内容(你设置了loading={null}),导致页面源码看不到实际渲染的HTML和数据,最终表现得像纯CSR应用。

解决方案

核心思路是区分服务器端和客户端的Redux配置:服务器端不需要持久化存储,直接创建普通Redux Store;客户端再初始化带持久化的Store并通过PersistGate包裹组件。

1. 修改Store创建逻辑(store/index.js)

改成函数式创建,根据环境判断是否启用持久化:

import { createStore } from "redux";
import { persistStore, persistReducer } from 'redux-persist';
import reducers from "../reducers";
import storage from 'redux-persist/lib/storage';

export const createReduxStore = (initialState = {}) => {
  // 服务器端:不使用redux-persist,直接创建Store
  if (typeof window === 'undefined') {
    return createStore(reducers, initialState);
  }

  // 客户端:启用持久化配置
  const persistConfig = {
    key: 'root',
    storage
  };

  const persistedReducer = persistReducer(persistConfig, reducers);
  const store = createStore(persistedReducer, initialState);
  const persistor = persistStore(store);
  
  return { store, persistor };
};

2. 调整_app.js的渲染逻辑

在服务器端直接渲染组件,客户端再用PersistGate包裹:

import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { ConfigProvider } from 'antd';
import { createReduxStore } from "../redux/store";
import theme from 'antd/es/theme';
import App from 'next/app';

function MyApp({ Component, pageProps, reduxStore }) {
  // 客户端环境:用PersistGate等待持久化数据恢复
  if (typeof window !== 'undefined') {
    const { store, persistor } = reduxStore;
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <ConfigProvider
            theme={{
              algorithm: theme.defaultAlgorithm,
              token: { 
                fontFamily: "DrSalvador",
                colorPrimary: "#f44"
              }
            }}
          >
            <Component {...pageProps} />
          </ConfigProvider>
        </PersistGate>
      </Provider>
    );
  }

  // 服务器端环境:直接渲染,跳过PersistGate
  return (
    <Provider store={reduxStore}>
      <ConfigProvider
        theme={{
          algorithm: theme.defaultAlgorithm,
          token: { 
            fontFamily: "DrSalvador",
            colorPrimary: "#f44"
          }
        }}
      >
        <Component {...pageProps} />
      </ConfigProvider>
    </Provider>
  );
}

// 每次请求创建独立的Store,避免服务器端缓存复用
MyApp.getInitialProps = async (appContext) => {
  const appProps = await App.getInitialProps(appContext);
  const reduxStore = createReduxStore();
  
  return {
    ...appProps,
    // 服务器端只传递store实例,客户端传递包含persistor的对象
    reduxStore: typeof window !== 'undefined' ? reduxStore : reduxStore.store
  };
};

export default MyApp;

3. 验证效果

修改完成后重新启动项目,访问页面并查看源码(Ctrl+U):

  • 服务器端会直接渲染index.js中getServerSideProps返回的数据和HTML结构,源码中能看到完整内容
  • 客户端加载完成后,redux-persist会恢复本地存储的状态,不影响SSR的初始渲染效果

内容的提问来源于stack exchange,提问作者Jack The Baker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:57:26