如何存储Moment.js日期以适配React-Big-Calendar事件?
解决React-Big-Calendar解析预存日期的问题
看起来你遇到的核心问题是localStorage只能存储字符串,直接存Date/Moment对象会被自动序列化成格式不兼容的字符串,导致取出后无法被React-Big-Calendar(RBC)正确解析。报错里的date["get" + method] is not a function就是因为RBC尝试调用日期对象的方法(比如getHours),但拿到的可能是无效的Date对象甚至原始字符串。
下面是具体的解决方案:
1. 正确的日期存储方式
因为localStorage只能存字符串,我们需要把日期序列化成ISO格式字符串或者时间戳(毫秒数),这两种格式跨浏览器兼容且能被RBC正确解析。
方案A:存储ISO格式字符串(推荐)
ISO格式(比如2018-05-15T15:00:00.000Z)是JavaScript Date对象的标准序列化格式,兼容性最好。
- 存储时:用Moment把日期转成ISO字符串
// 生成日期并转成ISO格式 const startMoment = moment("05/15/2018 11:00 AM", "MM/DD/YYYY hh:mm A"); const endMoment = moment("05/15/2018 12:00 PM", "MM/DD/YYYY hh:mm A"); const event = { id: 1, title: "测试事件", start: startMoment.toISOString(), end: endMoment.toISOString() }; // 存入localStorage(要转成JSON字符串) localStorage.setItem("calendarEvents", JSON.stringify([event])); - 取出时:把ISO字符串转回Date对象(或Moment对象)
// 从localStorage读取并解析 const storedEvents = JSON.parse(localStorage.getItem("calendarEvents")) || []; // 转换日期字段为Date对象 const validEvents = storedEvents.map(event => ({ ...event, start: new Date(event.start), end: new Date(event.end) })); // 把validEvents传给RBC的events属性
方案B:存储时间戳(毫秒数)
时间戳是从1970年开始的毫秒数,也是完全兼容的格式:
- 存储时:获取Moment/Date的时间戳并转成字符串
const startTimestamp = moment("05/15/2018 11:00 AM", "MM/DD/YYYY hh:mm A").valueOf(); const endTimestamp = moment("05/15/2018 12:00 PM", "MM/DD/YYYY hh:mm A").valueOf(); const event = { id: 1, title: "测试事件", start: startTimestamp.toString(), end: endTimestamp.toString() }; localStorage.setItem("calendarEvents", JSON.stringify([event])); - 取出时:把字符串转成数字,再生成Date对象
const storedEvents = JSON.parse(localStorage.getItem("calendarEvents")) || []; const validEvents = storedEvents.map(event => ({ ...event, start: new Date(parseInt(event.start)), end: new Date(parseInt(event.end)) }));
2. 为什么之前的方式会出错?
你直接存储new Date(date)生成的对象,localStorage会把它转成"[object Date]"这样的无用字符串;而如果存储的是"05/15/2018 11:00 AM"这种自定义格式的字符串,不同浏览器对new Date("自定义格式")的解析逻辑不一致,可能生成无效的Date对象(比如在某些浏览器中返回Invalid Date),导致RBC无法调用日期相关方法,从而抛出错误。
3. 配合Moment Localizer的优化
如果你在RBC中使用了Moment本地化器,也可以直接把存储的字符串转成Moment对象,RBC同样支持:
import { momentLocalizer } from 'react-big-calendar'; import moment from 'moment'; const localizer = momentLocalizer(moment); // 解析时转成Moment对象 const validEvents = storedEvents.map(event => ({ ...event, start: moment(event.start), end: moment(event.end) }));
内容的提问来源于stack exchange,提问作者rosemerryberry
相关产品推荐
相关产品推荐

