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
相关产品推荐
相关产品推荐

