Next.js页面刷新后isAuth登录状态重置问题求助
解决Next.js中localStorage保存登录状态刷新后重置的问题
你的代码存在几个问题导致刷新后状态重置,以下是修复方案:
问题分析
- 初始状态未从localStorage读取:你用空字符串作为
isAuth的初始值,页面加载时会先显示这个默认值,虽然后续useEffect会读取localStorage,但会出现状态闪烁,且服务端渲染时会导致初始状态不一致。 - 值类型不匹配:
localStorage只能存储字符串,当你调用setAuth(true)时,布尔值会被转为字符串"true"存入,读取时直接赋值会让isAuth变成字符串类型,后续逻辑易出错。 - 服务端访问localStorage风险:Next.js的App组件可能在服务端执行,此时访问
localStorage会报错,因为服务端没有window对象。
修复后的代码
export default function App({ Component, pageProps }) { // 函数式初始化state,避免服务端报错,同时直接从localStorage读取初始值 const [isAuth, setAuth] = useState(() => { if (typeof window !== 'undefined') { const storedAuth = localStorage.getItem('isAuth'); // 将存储的字符串转回布尔值,保证类型一致 return storedAuth ? JSON.parse(storedAuth) : false; } // 服务端渲染时默认返回未登录状态 return false; }); useEffect(() => { // 当isAuth变化时,同步更新localStorage,用JSON.stringify保证类型正确 localStorage.setItem('isAuth', JSON.stringify(isAuth)); }, [isAuth]); return ( <AppContext.Provider value={{ isAuth, setAuth }}> <Layout> <Component {...pageProps} /> </Layout> </AppContext.Provider> ); }
关键修改说明
- 函数式初始化state:直接在
useState中传入函数,仅在组件初始化时执行一次,既避免服务端访问localStorage报错,又能让组件加载时就拿到正确的登录状态,不会出现默认值闪烁。 - 统一值类型:用
JSON.stringify存入、JSON.parse读取,保证isAuth始终是布尔类型,避免字符串和布尔值混淆导致的逻辑错误。 - 精简副作用逻辑:去掉多余的初始化
useEffect,仅保留状态变化时同步localStorage的逻辑,避免重复操作。
内容的提问来源于stack exchange,提问作者Josip Marić
相关产品推荐
相关产品推荐

