Next.js中LocalStorage刷新后值恢复初始值的问题排查
问题分析与解决
你的代码出现刷新后LocalStorage值变回1的核心原因是组件挂载时的初始值写入逻辑覆盖了之前存储的内容,具体执行流程如下:
- 组件首次挂载(或刷新页面)时,
useState(1)先将testNum初始化为固定值1。 - 依赖
testNum的useEffect会立即触发,把当前的testNum(也就是1)写入LocalStorage,直接覆盖了之前点击按钮后存储的4。 - 此时读取LocalStorage的
useEffect才执行,但读到的已经是刚写入的1,最终页面和存储值都回到了初始状态。
简单来说,你通过两个useEffect实现的逻辑导致了「先写初始值,再读旧值」的错误,同时初始state没有优先从LocalStorage读取,而是直接用了固定值。
修复后的代码
import { useState, useEffect } from 'react' function Test() { // 初始化state时优先从LocalStorage读取,无存储值则用默认值1 const [testNum, setTestNum] = useState(() => { const data = window.localStorage.getItem("MY_TEST_ITEM"); return data ? JSON.parse(data) : 1; }); // 仅保留同步逻辑:testNum变化时更新LocalStorage useEffect(() => { window.localStorage.setItem("MY_TEST_ITEM", JSON.stringify(testNum)) }, [testNum]); return ( <div> <h1>{testNum}</h1> <button onClick={() => setTestNum(prev => prev + 3)}>Add</button> </div> ) } export default Test
关键修复点
- 用函数式初始化state:在组件挂载时直接读取LocalStorage,避免初始渲染后异步修改state导致的页面闪烁和存储覆盖问题。
- 移除多余的读取逻辑:不再需要单独的
useEffect来读取存储,初始值已经在state初始化阶段处理完成。 - 函数式更新state:点击事件中使用
setTestNum(prev => prev + 3),确保在多次快速点击时能正确累加(属于React状态更新的最佳实践)。
内容的提问来源于stack exchange,提问作者marko2304
相关产品推荐
相关产品推荐

