Next 14刷新后localStorage失效,初始状态始终为blue的解决方案
解决Next.js 14中React Context从localStorage初始化颜色状态的问题
在Next.js 14的客户端组件中,直接在useState初始化阶段访问localStorage会因为服务端渲染(SSR)/静态生成(SSG)环境中不存在localStorage,导致初始状态始终回退到默认值blue,无法读取本地存储的preferred_color。
修复方案
核心思路是延迟到客户端挂载后再读取localStorage,通过useEffect确保代码只在浏览器环境执行,同时保留类型安全校验:
'use client'; import { Dispatch, SetStateAction, createContext, useEffect, useState } from 'react'; type Color = 'blue' | 'green' | 'red' | 'orange' | 'violet'; interface ColorsContextProps { color: Color; setColor: Dispatch<SetStateAction<Color>>; } interface ColorsProviderProps { children: React.ReactNode; } export const ColorsContext = createContext({} as ColorsContextProps); export function ColorsProvider({ children }: ColorsProviderProps) { // 初始状态先设为默认值,避免服务端报错 const [color, setColor] = useState<Color>('blue'); // 客户端挂载后读取localStorage并更新状态 useEffect(() => { const savedColor = localStorage.getItem('preferred_color') as Color | null; // 校验值是否在允许的颜色列表中,避免无效值 if (savedColor && ['blue', 'green', 'red', 'orange', 'violet'].includes(savedColor)) { setColor(savedColor); } }, []); // 颜色变化时同步到localStorage useEffect(() => { localStorage.setItem('preferred_color', color); }, [color]); return ( <ColorsContext.Provider value={{ color, setColor }}> {children} </ColorsContext.Provider> ); }
关键修改说明
- 提取
Color类型别名,简化代码维护 - 初始
useState直接使用默认值blue,避免服务端执行时访问localStorage抛出错误 - 新增空依赖的
useEffect,确保仅在客户端组件挂载后执行一次,读取并校验本地存储的颜色值,有效则更新状态 - 保留原有的颜色同步
useEffect,确保颜色变更时自动保存到localStorage
内容的提问来源于stack exchange,提问作者Italo Covas
相关产品推荐
相关产品推荐

