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

Next.js 13.4中redux-persist存储创建失败问题及修正代码请求

Next.js 13.4 Redux + Redux-Persist 持久化错误修复方案

错误原因

该报错是因为 Redux-Persist 默认尝试在服务器端访问浏览器的 localStorage API,但 Next.js 13.4 App Router 的组件默认是服务器组件,服务器环境不存在 localStorage,导致存储初始化失败,最终回退到空存储(noop storage)。


修改后的完整代码

1. 安装依赖(未安装时执行)

npm install @reduxjs/toolkit react-redux redux-persist

2. store/index.ts

import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import cartReducer from './cartSlice';

// 仅在客户端环境启用持久化存储
const persistConfig = {
  key: 'root',
  storage: typeof window !== 'undefined' ? storage : undefined,
};

const persistedReducer = persistReducer(persistConfig, cartReducer);

export const store = configureStore({
  reducer: {
    cart: persistedReducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export const persistor = persistStore(store);

3. store/cartSlice.ts

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface CartItem {
  id: number;
  name: string;
  quantity: number;
  price: number;
}

interface CartState {
  items: CartItem[];
}

const initialState: CartState = {
  items: [],
};

const cartSlice = createSlice({
  name: 'cart',
  initialState,
  reducers: {
    addToCart: (state, action: PayloadAction<CartItem>) => {
      const existingItem = state.items.find(item => item.id === action.payload.id);
      if (existingItem) {
        existingItem.quantity += 1;
      } else {
        state.items.push({ ...action.payload, quantity: 1 });
      }
    },
    removeFromCart: (state, action: PayloadAction<number>) => {
      state.items = state.items.filter(item => item.id !== action.payload);
    },
    updateQuantity: (state, action: PayloadAction<{ id: number; quantity: number }>) => {
      const item = state.items.find(item => item.id === action.payload.id);
      if (item) {
        item.quantity = action.payload.quantity;
      }
    },
  },
});

export const { addToCart, removeFromCart, updateQuantity } = cartSlice.actions;
export default cartSlice.reducer;

4. 创建客户端组件 Providers.tsx

'use client';

import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store';

export default function Providers({ children }: { children: React.ReactNode }) {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        {children}
      </PersistGate>
    </Provider>
  );
}

5. 修改 layout.tsx

import './globals.css';
import type { Metadata } from 'next';
import Providers from './Providers';

export const metadata: Metadata = {
  title: 'Redux Persist Demo',
  description: 'Next.js 13.4 Redux Persist Example',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

核心修复要点

  • 环境判断:通过typeof window !== 'undefined'确保仅在客户端加载 localStorage,避免服务器端报错。
  • 客户端组件隔离:用'use client'标记包裹 Redux Provider 和 PersistGate,符合 Next.js App Router 的组件规则(Redux 是客户端状态管理,不能在服务器组件中使用)。
  • 序列化忽略:在 store 配置中忽略 Redux-Persist 的内置 action,避免序列化警告。

内容的提问来源于stack exchange,提问作者mvsr cm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:19:58