React待办列表开发:刷新后localStorage数据为空问题求助
React Todo列表页面刷新后localStorage数据丢失的解决方案
问题根源
你的代码存在逻辑顺序错误:
- 组件挂载时,
items初始化为空数组[] - 监听
items的useEffect会在首次渲染后执行,直接把空数组写入localStorage,覆盖了之前存储的有效数据 - 随后执行的初始化
useEffect读取localStorage时,数据已经被空数组覆盖,最终导致页面刷新后数据丢失
修复方案
方案1:直接在useState初始化时读取localStorage
将items的初始状态改为从localStorage直接读取,从根源避免初始空数组覆盖已有数据:
const SAVED_ITEMS = "savedItems"; function Todo() { // 初始化阶段直接从localStorage加载数据 const [items, setItems] = useState(() => { try { const savedItems = localStorage.getItem(SAVED_ITEMS); return savedItems ? JSON.parse(savedItems) : []; } catch (error) { console.error("解析本地存储数据失败:", error); return []; } }); // 仅当items状态变化时更新localStorage useEffect(() => { localStorage.setItem(SAVED_ITEMS, JSON.stringify(items)); }, [items]); // 你的待办项添加、删除等业务逻辑 }
方案2:给存储逻辑添加判断(兼容原有初始化方式)
如果不想修改useState的初始化方式,可以给第二个useEffect增加判断,避免初始空数组覆盖数据:
const SAVED_ITEMS = "savedItems"; function Todo() { const [items, setItems] = useState([]); useEffect(() => { const savedItems = JSON.parse(localStorage.getItem(SAVED_ITEMS)); if (savedItems) { setItems(savedItems); } }, []); useEffect(() => { // 仅当items不是初始空数组时才存储,避免覆盖已有数据 if (items.length > 0) { localStorage.setItem(SAVED_ITEMS, JSON.stringify(items)); } }, [items]); }
注意事项
- 操作
items状态时必须遵循React不可变原则,比如添加项时用setItems(prev => [...prev, newItem]),而非直接修改原数组 - 加入
try-catch可以避免localStorage中存储无效JSON时导致的页面报错
内容的提问来源于stack exchange,提问作者Raiffe Moura
相关产品推荐
相关产品推荐

