React支出追踪器使用localStorage存数据刷新丢失及getMonth报错问题
问题根因
useState传参错误:React的useState仅接收第一个参数作为状态初始值,你代码中useState(dummyExpenses,local)的第二个参数无效,状态始终默认加载示例数据,导致刷新后存储的内容不显示。- Date类型序列化丢失:JSON格式不支持Date对象,调用
JSON.stringify存储时,date字段的Date实例会被转为ISO格式字符串,JSON.parse读取回来后为普通字符串,没有getMonth方法,触发类型错误。
修复方案
1. 修正localStorage读取逻辑,恢复Date类型
读取本地存储的支出数据时,将date字段从字符串转回Date对象,同时将处理后的数据作为useState的唯一初始值。
修正后完整App.js代码
import React,{useState,useEffect} from "react"; import Expenses from "./components/Expenses"; import NewExpense from "./components/NewExpense/NewExpense"; const dummyExpenses = [ { id: "e1", title: "Toilet Paper", amount: 94.12, date: new Date(2020, 7, 14), }, { id: "e2", title: "New TV", amount: 799.49, date: new Date(2021, 2, 12) }, { id: "e3", title: "Car Insurance", amount: 294.67, date: new Date(2021, 2, 28), }, { id: "e4", title: "New Desk (Wooden)", amount: 450, date: new Date(2021, 5, 12), }, { id: "e5", title: "internet", amount: 400, date: new Date(2021, 3, 12), }, ]; // 读取本地存储并处理Date类型 const getInitialExpenses = () => { const localData = localStorage.getItem('expenses'); if (localData) { const parsedExpenses = JSON.parse(localData); // 将date字符串转回Date对象 return parsedExpenses.map(item => ({ ...item, date: new Date(item.date) })); } return dummyExpenses; } const App = ()=>{ // 直接传入处理后的初始值,用函数写法可以避免重复读取本地存储 const [expenses,setExpenses] = useState(getInitialExpenses); const addExpenseHandler = expense =>{ setExpenses(prevExpenses=>{ return[expense,...prevExpenses]; }); console.log(expense); }; // 存储逻辑保持不变,新添加的expense.date为Date对象,序列化后格式统一 useEffect(() => { localStorage.setItem('expenses', JSON.stringify(expenses)) }, [expenses]) return ( <div> <NewExpense onAddExpense = {addExpenseHandler}/> <Expenses items = {expenses}/> </div> ); } export default App;
2. Expenses组件无需修改
修复后支出数据的date字段已恢复为Date对象,原有getMonth()调用可以正常执行,筛选逻辑不受影响。
内容的提问来源于stack exchange,提问作者M. R
相关产品推荐
相关产品推荐

