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

NextJS(redux-thunk)中Store.js无法使用localStorage的页面生成报错

NextJS + Redux-Thunk 中使用 localStorage 初始化 Store 报错的解决方法

问题原因

NextJS 在服务端渲染(SSR)或静态页面生成(SSG)阶段,代码运行在 Node.js 环境中,这个环境里不存在浏览器的 localStorage 对象。你的 Store.js 在初始化 initialState 时直接调用 localStorage.getItem,导致服务端执行时抛出错误。

解决方案

方案1:在初始化时判断运行环境

修改 initialState 的定义,通过判断 window 对象是否存在,仅在客户端环境下读取 localStorage:

let initialState = {
  cart: {
    cartItems: typeof window !== 'undefined' 
      ? JSON.parse(localStorage.getItem("cartItems") || '[]') 
      : [],
  }
};

方案2:在 Reducer 中处理初始状态

把读取 localStorage 的逻辑移到 cartReducer 里,Reducer 在客户端运行时可以安全访问浏览器 API:

修改 cartsReducer.js:

// 定义 reducer 的初始状态
const initialCartState = {
  cartItems: typeof window !== 'undefined' 
    ? JSON.parse(localStorage.getItem("cartItems") || '[]') 
    : []
};

export const cartReducer = (state = initialCartState, action) => {
  // 原有的 reducer 逻辑
  switch(action.type) {
    // ...你的 case 处理
    default:
      return state;
  }
};

然后 Store.js 中的 initialState 可以简化为:

let initialState = {};

方案3:在客户端组件中 Hydrate 数据

保持 Store 的初始状态为空数组,在 NextJS 的 _app.js 中,利用 useEffect 在客户端组件挂载后,从 localStorage 读取数据并 dispatch 到 Store:

  1. 先修改 Store.js 的初始状态:
let initialState = {
  cart: {
    cartItems: [],
  }
};
  1. 在 _app.js 中添加逻辑:
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
// 假设你有一个用于更新购物车的 action
import { setCartItems } from '../actions/cartActions';

function MyApp({ Component, pageProps }) {
  const dispatch = useDispatch();

  useEffect(() => {
    const savedCartItems = localStorage.getItem('cartItems');
    if (savedCartItems) {
      dispatch(setCartItems(JSON.parse(savedCartItems)));
    }
  }, [dispatch]);

  return <Component {...pageProps} />;
}

export default MyApp;

需要确保你已经定义了对应的 setCartItems action 和 reducer 处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:10:30