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

React学生信息管理页面刷新后数据丢失问题求助

解决React学生信息管理程序刷新后数据丢失问题

我正在为教师开发一款简易的学生信息管理React程序,程序设有3个输入框,供教师手动录入学生的名、姓和入学日期。但录入的信息在页面刷新、关闭并重新打开程序后会丢失,请问该如何解决此问题?

原始代码:

import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
  const [students, setStudents] = useState([]);
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");

  useEffect(() => {
    const storedStudents = localStorage.getItem("students");
    console.log("Stored Students:", storedStudents);
    if (storedStudents) {
      setStudents(JSON.parse(storedStudents));
    }
  }, []);

  useEffect(() => {
    localStorage.setItem("students", JSON.stringify(students));
  }, [students]);

  const formatDate = (date) => {
    const options = { year: "numeric", month: "numeric", day: "numeric" };
    return new Date(date).toLocaleDateString("en-US", options);
  };

  const calculateEndDateAndSave = () => {
    const startDateObj = new Date(startDate);
    const endDateObj = new Date(
      startDateObj.getTime() + 4 * 7 * 24 * 60 * 60 * 1000
    );

    setEndDate(formatDate(endDateObj));

    const newStudent = {
      firstName: firstName,
      lastName: lastName,
      startDate: formatDate(startDate),
      endDate: formatDate(endDateObj),
    };

    setStudents([...students, newStudent]);
    setFirstName("");
    setLastName("");
    setStartDate("");
  };

  const deleteStudent = (index) => {
    const newStudents = [...students];
    newStudents.splice(index, 1);
    setStudents(newStudents);
  };

  return (
    <div className="mainPage">
      <h1>Student Information</h1>
      <label>
        First Name:
        <input
          type="text"
          value={firstName}
          onChange={(e) => setFirstName(e.target.value)}
        />
      </label>
      <br />
      <label>
        Last Name:
        <input
          type="text"
          value={lastName}
          onChange={(e) => setLastName(e.target.value)}
        />
      </label>
      <br />
      <label>
        Start Date:
        <input
          type="date"
          value={startDate}
          onChange={(e) => setStartDate(e.target.value)}
        />
      </label>
      <br />
      <div className="button-container">
        <button onClick={calculateEndDateAndSave}>
          Calculate and Save End Date
        </button>{" "}
      </div>
      <br />
      <h2>Registered Students</h2>
      <ul>
        {students.map((student, index) => (
          <li key={index}>
            <b>
              {student.firstName} {student.lastName}
            </b>{" "}
            --- <b>Start Date:</b> {student.startDate}, <b>End Date:</b>{" "}
            {student.endDate}
            <button
              style={{ marginLeft: "10px" }}
              onClick={() => deleteStudent(index)}
            >
              Delete
            </button>{" "}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

你的代码已经尝试用localStorage做数据持久化,但可以通过优化初始化逻辑和增加异常处理提升稳定性,以下是完善后的代码:

import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
  // 初始化时直接从localStorage读取数据,替代异步加载
  const [students, setStudents] = useState(() => {
    try {
      const storedStudents = localStorage.getItem("students");
      return storedStudents ? JSON.parse(storedStudents) : [];
    } catch (error) {
      console.error("读取本地存储数据失败:", error);
      return [];
    }
  });
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");

  // 监听students变化,同步到localStorage并增加异常捕获
  useEffect(() => {
    try {
      localStorage.setItem("students", JSON.stringify(students));
    } catch (error) {
      console.error("保存数据到本地存储失败:", error);
    }
  }, [students]);

  const formatDate = (date) => {
    const options = { year: "numeric", month: "numeric", day: "numeric" };
    return new Date(date).toLocaleDateString("en-US", options);
  };

  const calculateEndDateAndSave = () => {
    const startDateObj = new Date(startDate);
    const endDateObj = new Date(
      startDateObj.getTime() + 4 * 7 * 24 * 60 * 60 * 1000
    );

    setEndDate(formatDate(endDateObj));

    const newStudent = {
      firstName: firstName,
      lastName: lastName,
      startDate: formatDate(startDate),
      endDate: formatDate(endDateObj),
    };

    // 使用函数式更新确保基于最新state操作
    setStudents(prevStudents => [...prevStudents, newStudent]);
    setFirstName("");
    setLastName("");
    setStartDate("");
  };

  const deleteStudent = (index) => {
    // 同样使用函数式更新避免闭包陷阱
    setStudents(prevStudents => {
      const newStudents = [...prevStudents];
      newStudents.splice(index, 1);
      return newStudents;
    });
  };

  return (
    <div className="mainPage">
      <h1>Student Information</h1>
      <label>
        First Name:
        <input
          type="text"
          value={firstName}
          onChange={(e) => setFirstName(e.target.value)}
        />
      </label>
      <br />
      <label>
        Last Name:
        <input
          type="text"
          value={lastName}
          onChange={(e) => setLastName(e.target.value)}
        />
      </label>
      <br />
      <label>
        Start Date:
        <input
          type="date"
          value={startDate}
          onChange={(e) => setStartDate(e.target.value)}
        />
      </label>
      <br />
      <div className="button-container">
        <button onClick={calculateEndDateAndSave}>
          Calculate and Save End Date
        </button>{" "}
      </div>
      <br />
      <h2>Registered Students</h2>
      <ul>
        {students.map((student, index) => (
          <li key={index}>
            <b>
              {student.firstName} {student.lastName}
            </b>{" "}
            --- <b>Start Date:</b> {student.startDate}, <b>End Date:</b>{" "}
            {student.endDate}
            <button
              style={{ marginLeft: "10px" }}
              onClick={() => deleteStudent(index)}
            >
              Delete
            </button>{" "}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

关键优化说明:

  • 同步初始化数据:在useState初始化函数中直接读取localStorage,避免原代码异步加载导致的短暂空列表状态,提升页面加载体验
  • 异常捕获:读取和写入localStorage时增加try/catch,防止数据格式错误或浏览器存储配额不足等问题导致程序崩溃
  • 函数式更新state:使用prevStudents => ...的方式更新状态,确保每次操作都基于最新的state值,避免闭包陷阱

补充提示:

  • localStorage的数据会永久保存在用户本地浏览器中,除非手动清除或通过代码删除
  • 如果需要跨设备同步数据,后续可以接入后端API,将数据存储到服务器数据库中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:25:32