Next.js 13中ReferenceError: localStorage is not defined错误修复求助
修复Next.js 13中Redux store的localStorage未定义错误
错误信息
[1] - error src\redux\store.js (12:15) @ localStorage
[1] - error ReferenceError: localStorage is not defined

问题代码(store.js)
import { createStore, combineReducers, applyMiddleware } from "redux"; import thunk from "redux-thunk"; import { composeWithDevTools } from "redux-devtools-extension"; import { rootReducer } from "./rootReducer"; const finalReducer = combineReducers({ rootReducer, }); const intialState = { rootReducer: { cartItems: localStorage.getItem("cartItems") ? JSON.parse(localStorage.getItem("cartItems")) : [], }, }; const middleware = [thunk]; const store = createStore( finalReducer, intialState, composeWithDevTools(applyMiddleware(...middleware)) ); export default store;
修复方案
原因分析
Next.js 13默认采用服务器端渲染(SSR)或静态生成(SSG),在服务器端执行代码时,localStorage是浏览器专属API,Node.js环境中不存在该对象,直接访问就会抛出"未定义"错误。
方案一:初始化时判断浏览器环境(快速修复)
修改initialState的定义,先检查localStorage是否存在,再读取数据:
const initialState = { rootReducer: { cartItems: typeof localStorage !== 'undefined' ? JSON.parse(localStorage.getItem("cartItems") || "[]") : [], }, };
额外添加|| "[]"是为了避免localStorage中无数据时,JSON.parse解析null报错。
方案二:在客户端组件中加载数据(符合Next.js规范)
把读取localStorage的逻辑移到客户端组件中,避免服务器端执行浏览器专属代码:
- 修改rootReducer的初始状态
// rootReducer.js const initialState = { cartItems: [], }; export const rootReducer = (state = initialState, action) => { switch (action.type) { case 'LOAD_CART_ITEMS': return { ...state, cartItems: action.payload, }; // 保留原有其他action处理逻辑 default: return state; } };
- 在客户端根组件中触发加载逻辑
创建或修改layout.js/_app.js(添加'use client'声明为客户端组件):
'use client' import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; export default function RootLayout({ children }) { const dispatch = useDispatch(); useEffect(() => { const savedCart = localStorage.getItem('cartItems'); const cartItems = savedCart ? JSON.parse(savedCart) : []; dispatch({ type: 'LOAD_CART_ITEMS', payload: cartItems }); }, [dispatch]); return ( <html lang="en"> <body>{children}</body> </html> ); }
这种方式更贴合Next.js的渲染模型,将客户端专属操作限制在浏览器环境执行,彻底避免服务器端的兼容性问题。
内容的提问来源于stack exchange,提问作者Nuwan Chamikara
相关产品推荐
相关产品推荐

