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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:27:03