刷新时localStorage被清空、待办丢失,如何修复React应用该问题?
解决页面刷新后待办事项丢失的问题
你的代码核心问题是组件初始化时先将空数组写入localStorage,覆盖了原有数据,同时初始状态没有从localStorage读取值。以下是修复方案:
关键修改点
1. 初始化状态时直接读取localStorage
把todoList的初始值改为从localStorage读取,避免用空数组覆盖已有数据:
const [todoList, setTodoList] = useState(() => { const savedTodos = localStorage.getItem("todos"); // 读取到数据就解析,否则返回空数组 return savedTodos ? JSON.parse(savedTodos) : []; });
2. 移除多余的挂载阶段useEffect
原来的空依赖useEffect可以删除,因为初始化状态时已经完成了读取操作,避免重复设置状态导致的不必要渲染。
3. 优化存储逻辑的边界处理
添加异常捕获,避免隐私模式等场景下localStorage无法写入的报错:
useEffect(() => { try { localStorage.setItem("todos", JSON.stringify(todoList)); } catch (e) { console.error("存储待办事项失败:", e); } }, [todoList]);
完整修复后的代码
import React, { useEffect, useState } from "react"; import Head from "next/head"; export default function Home() { // 初始化输入框为空字符串,避免出现undefined const [inputValue, setInputValue] = useState(""); // 初始化时从localStorage加载数据 const [todoList, setTodoList] = useState(() => { const savedTodos = localStorage.getItem("todos"); return savedTodos ? JSON.parse(savedTodos) : []; }); useEffect(() => { try { localStorage.setItem("todos", JSON.stringify(todoList)); } catch (e) { console.error("存储待办事项失败:", e); } }, [todoList]); const formSubmit = (e) => { e.preventDefault(); // 过滤空白内容 if (!inputValue.trim()) return; // 使用时间戳生成唯一id,避免删除项后id重复 setTodoList(prev => [ ...prev, { id: Date.now(), name: inputValue.trim(), }, ]); setInputValue(""); }; return ( <div> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <form onSubmit={formSubmit}> <input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} placeholder="输入待办事项" /> <input type="submit" value="添加" /> </form> <ul className="list"> {todoList.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }
额外优化说明
- 给
inputValue设置初始空字符串,避免输入框显示undefined - 用
Date.now()生成todo的唯一ID,解决删除列表项后新增项ID重复的问题 - 添加空白内容过滤,避免创建空的待办事项
内容的提问来源于stack exchange,提问作者Sjoerd Vermeijden
相关产品推荐
相关产品推荐

