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

