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

Next.js 13设客户端渲染仍出现localStorage未定义SSR错误

解决Next.js 13中"use client"组件访问localStorage报错的问题

问题原因

即使给组件加上了"use client"指令,Next.js 13的客户端组件在初始hydration阶段仍会在服务器端执行部分代码逻辑。直接在组件顶层访问localStorage(服务器环境不存在该对象),就会触发ReferenceError: localStorage is not defined错误。

修复方案

将localStorage的读写操作放到客户端安全的执行时机——比如组件挂载后的useEffect钩子中,同时用useState管理语言状态,避免服务器端执行时访问不存在的API。

修改后的完整代码

"use client";

import Image from "next/image";
import { useState, useEffect } from "react";
import chevron from "../public/icons/chevron.png";

export default function LanguageSwitch() {
    // 用useState初始化默认语言,避免服务器端渲染时出错
    const [lang, setLang] = useState<string | null>("SRB");
    const [openMenu, setOpenMenu] = useState(false);

    // 组件挂载后(仅客户端执行)读取localStorage中的语言设置
    useEffect(() => {
        const savedLang = localStorage.getItem("lang");
        if (savedLang) {
            setLang(savedLang);
        }
    }, []);

    const handleLanguage = () => {
        // 计算新的语言值
        const newLang = lang === "SRB" ? "ENG" : "SRB";
        // 更新状态
        setLang(newLang);
        // 写入localStorage
        localStorage.setItem("lang", newLang);
    };

    return (
        <div className="language-switch" onClick={() => setOpenMenu(p => !p)} >
            <p className="menu-item">{lang}</p>
            <Image src={chevron} alt="下拉箭头" />
            <div>
                {openMenu && (
                    <p onClick={handleLanguage} className="menu-item language-select">
                        {lang === "SRB" ? "ENG" : "SRB"}
                    </p>
                )}
            </div>
        </div>
    );
}

关键改动说明

  • 用useState初始化语言状态为默认的"SRB",保证服务器端渲染时能正常生成HTML,不会触发错误
  • 新增useEffect钩子,仅在客户端组件挂载后执行,此时读取localStorage并更新状态,避免服务器端访问该API
  • 修改handleLanguage函数,先计算新语言值,同步更新状态和localStorage,保证状态和存储的一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:53:22