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

React迁移Next.js时提示localStorage is not defined怎么解决?

问题解决方案

问题根源是Next.js服务端渲染阶段没有window对象,自然不存在localStorage,你代码里useState的初始化回调会在服务端渲染组件时直接执行,因此触发报错。

方案1:将localStorage读取逻辑移入useEffect

useEffect仅在客户端挂载后执行,天然避开服务端环境,修改后的状态初始化代码如下:

import { useState, useEffect } from 'react'
import jwt_decode from 'jwt-decode'

// 组件内代码
// 初始值先设为null
const [authTokens, setAuthTokens] = useState(null)
const [user, setUser] = useState(null)

useEffect(() => {
  // 客户端执行时读取localStorage
  const storedTokens = localStorage.getItem('authTokens')
  if (storedTokens) {
    const parsedTokens = JSON.parse(storedTokens)
    setAuthTokens(parsedTokens)
    setUser(jwt_decode(parsedTokens.access))
  }
}, [])

登录函数本身是用户交互触发的事件回调,仅会在客户端执行,原有逻辑无需修改,稳妥起见也可以加环境判断:

if(response.status == 200) {
    setAuthTokens(data)
    setUser(jwt_decode(data.access))
    // 加环境判断兼容极端情况
    if (typeof window !== 'undefined') {
        localStorage.setItem('authTokens', JSON.stringify(data))
    }
    router.push('/')
}

方案2:封装localStorage安全访问工具

如果项目中多处用到localStorage,可以统一封装工具函数避免重复判断:

// 新建utils/storage.js
export const safeLocalStorage = {
  getItem: (key) => {
    if (typeof window === 'undefined') return null
    return localStorage.getItem(key)
  },
  setItem: (key, value) => {
    if (typeof window === 'undefined') return
    localStorage.setItem(key, value)
  },
  removeItem: (key) => {
    if (typeof window === 'undefined') return
    localStorage.removeItem(key)
  }
}

后续所有操作localStorage的地方都替换为该工具即可:

// 初始化也可以直接用,服务端会自动返回null
const [authTokens, setAuthTokens] = useState(() => safeLocalStorage.getItem('authTokens') ? JSON.parse(safeLocalStorage.getItem('authTokens')) : null)

Next.js 13+ App Router额外注意

如果使用App Router,需要在使用localStorage的组件顶部添加'use client'标记,标记该组件为客户端组件,再配合上述两种方案即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:24:03