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

React 18 + FullCalendar 5:如何获取接下来X个即将到来的事件?

获取React FullCalendar中带重复规则的即将到来事件

FullCalendar的RRule插件底层依赖RRule库,我们可以直接用这个库解析重复事件规则,生成具体的未来事件实例,再筛选出需要的结果。

步骤1:确保RRule库可用

如果项目未安装,先执行:

npm install rrule

步骤2:编写工具函数解析重复事件

创建工具函数,将带rrule的事件转换为未来的具体事件实例:

import { RRule, WEEKDAY } from 'rrule';

// 映射自定义星期枚举到RRule的WEEKDAY常量
const weekdayMap = {
  Friday: WEEKDAY.FR
  // 按需添加其他星期映射,比如Monday: WEEKDAY.MO
};

// 获取指定数量的即将到来事件
const getUpcomingEvents = (events, count, today = new Date()) => {
  const upcoming = [];
  
  events.forEach(event => {
    if (!event.rrule) return; // 跳过非重复事件
    
    // 转换RRule配置格式,适配RRule库要求
    const rruleConfig = {
      ...event.rrule,
      freq: RRule[event.rrule.freq.toUpperCase()], // 把'monthly'转为RRule.MONTHLY
      byweekday: event.rrule.byweekday.map(day => weekdayMap[day])
    };
    
    const rule = new RRule(rruleConfig);
    
    // 获取今日起未来1年内的所有重复事件实例(可按需调整时间范围)
    const futureInstances = rule.between(today, new Date(today.getFullYear() + 1, today.getMonth()), true);
    
    // 给每个实例附加原事件的元数据
    futureInstances.forEach(date => {
      upcoming.push({
        ...event,
        start: date.toISOString().split('T')[0],
        id: `${event.id}-${date.getTime()}` // 生成唯一ID避免冲突
      });
    });
  });
  
  // 按日期排序后取前count个
  return upcoming.sort((a, b) => new Date(a.start) - new Date(b.start)).slice(0, count);
};

步骤3:在组件中使用

在你的useEffect中调用函数获取结果:

useEffect(() => {
  const today = new Date();
  // 获取接下来2个即将到来的事件
  const nextTwoEvents = getUpcomingEvents(INITIAL_EVENTS, 2, today);
  console.log('即将到来的事件:', nextTwoEvents);
  // 可将结果存入state,供dashboard等组件使用
}, [INITIAL_EVENTS]);

注意事项

  • 你的INITIAL_EVENTS中两个事件id重复(均为321),建议修改为唯一值,避免渲染或筛选异常
  • 若需包含当天事件,可将between的起始参数改为new Date(today.setHours(0, 0, 0, 0))
  • 可根据业务需求调整未来事件的查询时间范围

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:20:35