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

Next.js 13配置Redux Toolkit持久化遇存储创建失败求助

Next.js 13 实现 Redux Toolkit 持久化的正确方案

问题原因

你遇到的redux-persist failed to create sync storage. falling back to noop storage错误,核心原因是Next.js 服务端渲染(SSR)环境中不存在浏览器的localStorage,而redux-persist默认依赖localStorage作为存储介质,服务端初始化时无法访问该对象,因此触发警告并回退到空操作存储。

解决方案

1. 修改 store.js:适配服务端/客户端存储

替换默认的storage导入,添加服务端 fallback 的空存储实现,确保在服务端不会报错:

import { configureStore } from "@reduxjs/toolkit";
import authenticateSlice from "./slices/authenticateSlice";
import { persistReducer } from "redux-persist";
import createWebStorage from "redux-persist/lib/storage/createWebStorage";
import { encryptTransform } from "redux-persist-transform-encrypt";
import { combineReducers } from "redux";

// 创建服务端用的空存储,避免SSR报错
const createNoopStorage = () => {
  return {
    getItem() { return Promise.resolve(null); },
    setItem(_key, value) { return Promise.resolve(value); },
    removeItem() { return Promise.resolve(); },
  };
};

// 客户端用localStorage,服务端用空存储
const storage = typeof window !== "undefined" 
  ? createWebStorage("local") 
  : createNoopStorage();

const reducers = combineReducers({
  auth: authenticateSlice.reducer,
});

let transforms = null;

if (process.env.NODE_ENV === "production") {
  const encrypt = encryptTransform({
    secretKey: process.env.NEXT_PUBLIC_REDUX_SECRET,
    onError: (error) => {
      // 可在这里添加错误处理逻辑
    },
  });
  transforms = [encrypt];
}

const persistConfig = {
  key: "root",
  storage,
  transforms,
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = configureStore({
  reducer: persistedReducer,
  // Redux Toolkit 默认已包含thunk,无需手动添加
  // middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
});

export default store;

2. 修改 _app.js:确保persistStore仅在客户端初始化

persistStore依赖浏览器环境,需避免在服务端执行,可通过useEffect延迟初始化:

import "@/styles/globals.css";
import Head from "next/head";
import Template from "template/index";
import React, { useEffect, useState } from "react";
import store from "next-redux/store";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import LinearProgress from "@mui/material/LinearProgress";

const App = ({ Component, pageProps }) => {
  const [persistor, setPersistor] = useState(null);

  useEffect(() => {
    // 仅在客户端初始化persistStore
    import("redux-persist").then(({ persistStore }) => {
      setPersistor(persistStore(store));
    });
  }, []);

  // 等待persistor初始化完成再渲染
  if (!persistor) {
    return <LinearProgress />;
  }

  return (
    <>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Provider store={store}>
        <PersistGate persistor={persistor} loading={<LinearProgress />}>
          <Template>
            <Component {...pageProps} />
          </Template>
        </PersistGate>
      </Provider>
    </>
  );
};

export default React.memo(App);

关键注意点

  • 环境区分:始终确保浏览器专属API(如localStorage、persistStore)仅在客户端执行
  • Redux Toolkit 内置中间件:无需手动添加thunk,configureStore默认已包含
  • 加密逻辑:生产环境的加密转换保持不变,仅在客户端生效

内容的提问来源于stack exchange,提问作者Jc John

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:34:59