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

React+TypeScript下FullCalendar添加事件不显示及API存储问题

问题1:添加的事件未在日历显示的解决方法

核心问题是日期格式不兼容:FullCalendar要求事件的start字段必须是可被JavaScript Date对象解析的格式(如ISO 8601:YYYY-MM-DDTHH:mm:ss),但你当前用DD/MM/YYYY拼接出来的字符串无法被正确解析,导致日历无法识别事件时间。

修复步骤:

  1. 在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')}`;
}
  1. 修改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('');
}
  1. 在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:42:20