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

刷新时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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:05:18