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
相关产品推荐
相关产品推荐

