You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React严格模式下LocalStorage数据刷新重置问题排查

问题原因

React严格模式在开发环境下会刻意重复执行组件的挂载/卸载流程,包括副作用函数(useEffect),这直接导致了你的localStorage数据被意外覆盖。

结合你的代码,严格模式下的执行顺序是这样的:

  1. 第一次组件挂载:
    • 第一个useEffect从localStorage读取数据并更新到store
    • 第二个useEffect触发,把store里的正确数据存回localStorage
  2. 严格模式强制卸载组件后重新挂载:
    • store回到初始值(比如空数组)
    • 第二个useEffect因notes从正确值变回初始值而触发,把初始值写入localStorage,直接覆盖了之前的有效数据
    • 重新挂载的第一个useEffect读取到的已经是被覆盖的初始值,最终导致页面刷新后数据重置
解决方法

方法一:把数据读写逻辑移到状态管理中(推荐)

如果你的状态管理用的是Zustand(从useAppStore的调用方式推测),可以直接在store初始化时读取localStorage,更新时同步写入,彻底避免组件副作用的干扰:

const useAppStore = create((set) => ({
  // 初始化时直接加载localStorage数据
  notes: JSON.parse(localStorage.getItem("react-todoList") || "[]"),
  setNotes: (newNotes) => {
    set({ notes: newNotes });
    // 更新时同步写入localStorage
    localStorage.setItem("react-todoList", JSON.stringify(newNotes));
  },
}));

之后组件里的两个useEffect都可以删掉,不管严格模式如何执行,store都会优先读取localStorage的有效数据,不会出现重置问题。

方法二:给组件副作用加判断逻辑

如果不想修改store,可以在第二个useEffect里增加判断,避免把初始值写入localStorage:

useEffect(() => {
  const storedNotes = JSON.parse(localStorage.getItem("react-todoList") || "[]");
  // 仅当当前notes和localStorage数据不一致时才写入
  if (JSON.stringify(notes) !== JSON.stringify(storedNotes)) {
    localStorage.setItem("react-todoList", JSON.stringify(notes));
  }
}, [notes]);

这样即使严格模式重复挂载组件,初始值也不会覆盖localStorage里的有效数据,第一个useEffect读取的始终是正确内容。

内容的提问来源于stack exchange,提问作者Muaz zia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:07:20