React+TypeScript下FullCalendar添加事件不显示及API存储问题
问题1:添加的事件未在日历显示的解决方法
核心问题是日期格式不兼容:FullCalendar要求事件的start字段必须是可被JavaScript Date对象解析的格式(如ISO 8601:YYYY-MM-DDTHH:mm:ss),但你当前用DD/MM/YYYY拼接出来的字符串无法被正确解析,导致日历无法识别事件时间。
修复步骤:
- 在
AddEventModal.tsx中添加日期格式转换函数,将DD/MM/YYYY转为YYYY-MM-DD:
function convertToISODate(dateStr: string): string { const [day, month, year] = dateStr.split('/'); // 确保月份和日期是两位数格式 return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`; }
- 修改
handleFormSubmit中的start字段生成逻辑,同时添加基础格式验证:
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 验证输入格式是否正确 if (!eventDate.match(/^\d{2}\/\d{2}\/\d{4}$/) || !eventTime.match(/^\d{2}:\d{2}:\d{2}$/)) { alert('请输入正确的日期(DD/MM/YYYY)和时间(HH:mm:ss)格式'); return; } const isoDate = convertToISODate(eventDate); const newEvent: EventInput = { title: 'Novo Evento', start: `${isoDate}T${eventTime}`, allDay: false, }; onAddEvent(newEvent); onClose(); setEventDate(''); setEventTime(''); }
- 在
Calendar.tsx中使用函数式状态更新,避免闭包导致的状态更新异常:
const handleModalSubmit = (newEvent: EventInput) => { // 基于前一个状态更新,确保拿到最新的事件列表 setEvents(prevEvents => [...prevEvents, newEvent]); };
问题2:通过API保存事件数据的实现
1. 前端发送请求到后端API
修改Calendar.tsx中的handleModalSubmit,添加API调用逻辑(以原生fetch为例,也可替换为axios):
const handleModalSubmit = async (newEvent: EventInput) => { try { // 发送POST请求到后端接口 const response = await fetch('/api/events', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(newEvent), }); if (!response.ok) { throw new Error('保存事件失败'); } // 仅在API保存成功后更新本地日历状态 setEvents(prevEvents => [...prevEvents, newEvent]); } catch (error) { console.error('保存事件出错:', error); alert('无法保存事件,请稍后重试'); } };
2. 初始化日历数据(从API加载已有事件)
在Calendar.tsx中添加useEffect,组件挂载时拉取已存储的事件:
import { useState, useEffect } from 'react'; // ... 其他代码 ... export function Calendar() { const [isOpen, setIsOpen] = useState(false); const [events, setEvents] = useState<EventInput[]>([]); // 组件挂载时加载已有事件 useEffect(() => { const fetchEvents = async () => { try { const response = await fetch('/api/events'); const data = await response.json(); setEvents(data); } catch (error) { console.error('加载事件出错:', error); } }; fetchEvents(); }, []); // ... 其他函数 ... }
3. 后端API示例(Node.js/Express)
后端需要提供对应的接口接收并存储事件,以下是极简示例(实际项目需替换为真实数据库):
const express = require('express'); const app = express(); app.use(express.json()); // 模拟数据库存储 let events = []; // 获取所有事件 app.get('/api/events', (req, res) => { res.json(events); }); // 添加新事件 app.post('/api/events', (req, res) => { const newEvent = { id: Date.now().toString(), // 生成唯一ID ...req.body }; events.push(newEvent); res.status(201).json(newEvent); }); app.listen(3001, () => console.log('API服务器运行在3001端口'));
内容的提问来源于stack exchange,提问作者mateusj
相关产品推荐
相关产品推荐

