Next.js中利用localStorage持久化React状态,解决页面导航后状态重置问题
解决Next.js页面导航后状态重置的问题
我懂你碰到的痛点——每次从About页面回到首页,test状态都会被useState(true)重置,导致sample text又显示出来,哪怕你用了localStorage也没解决。问题出在组件重新挂载时,useState的初始值会优先执行,覆盖你从localStorage读取的状态,而且原来的useEffect逻辑还有循环更新的问题。
下面是修改后的代码,完美解决这个需求:
import Link from "next/link"; import { useState, useEffect } from "react"; export default function IndexPage() { // 初始化时从 localStorage 读取状态,处理首次加载或 localStorage 不存在的情况 const [test, setTest] = useState(() => { if (typeof window !== 'undefined') { const saved = localStorage.getItem("test"); return saved !== null ? JSON.parse(saved) : true; } // 服务端渲染时默认返回 true return true; }); const handleClick = (path) => { if (path === "/about") { setTest(false); } }; // 只有当 test 变化时,同步到 localStorage useEffect(() => { if (typeof window !== 'undefined') { localStorage.setItem("test", JSON.stringify(test)); } }, [test]); return ( <div> Hello World.{" "} <Link href="/about"> <a onClick={() => handleClick("/about")}>About</a> </Link> {test && <p>sample text</p>} </div> ); }
关键修改点说明:
- 从localStorage初始化状态:使用useState的函数式初始化(传入一个函数),这样只会在组件挂载时执行一次。同时判断
window是否存在,避免Next.js服务器端渲染时访问localStorage报错,首次加载或localStorage无数据时默认返回true。 - 简化useEffect逻辑:原来的useEffect里调用
setTest会触发循环更新(test变化→useEffect执行→setTest→test再变化),现在只负责把当前test状态同步到localStorage,不再反向修改状态。 - 持久化状态生效:当你点击About按钮设置
test为false后,localStorage会保存这个值;回到首页时,组件初始化会直接读取localStorage的false,不会被初始值true覆盖,因此sample text不会再渲染。
测试一下:点击About跳转后,返回首页,sample text应该消失,而且刷新页面后状态也会保持哦!
内容的提问来源于stack exchange,提问作者dev_el
相关产品推荐
相关产品推荐

