React FullCalendar:如何获取非当前视图的未来事件
解决方案:获取FullCalendar中所有未来事件(含远期重复事件)
核心问题
getEvents()无参数时仅返回当前视图内的事件,要获取远期未来事件,需利用该方法的时间范围参数,或自行维护事件数据并解析重复规则。
方法1:使用getEvents(start, end)指定时间范围
这是最简单的方案,FullCalendar会自动解析重复事件的所有实例,返回指定时间范围内的全部事件:
const todayStr = new Date().toISOString().replace(/T.*$/, '') const [futureEvents, setFutureEvents] = useState([]); useEffect(() => { const calendarApi = calendarRef.current.getApi(); // 定义时间范围:从今天开始,到5年后结束(可根据需求调整) const startDate = new Date(todayStr); const endDate = new Date(); endDate.setFullYear(endDate.getFullYear() + 5); // 获取该范围内的所有事件 const events = calendarApi.getEvents(startDate, endDate); const calendarEvents = events.map(i => i.toPlainObject()); // 按开始时间升序排序 const sortedEvents = calendarEvents.sort((a, b) => new Date(a.start) - new Date(b.start)); setFutureEvents(sortedEvents); // eslint-disable-next-line react-hooks/exhaustive-deps }, [calendarRef]);
方法2:自行维护事件数据并解析重复规则
如果不想依赖CalendarAPI,可直接基于INITIAL_EVENTS,使用rrule库解析重复事件生成未来实例:
- 安装依赖:
npm install rrule
- 编写解析函数:
import { RRule } from 'rrule'; const getFutureEvents = (events, today) => { const futureEvents = []; const todayDate = new Date(today); events.forEach(event => { // 处理无重复规则的单次事件 if (!event.rrule) { const eventStart = new Date(event.start || event.rrule?.dtstart); if (eventStart >= todayDate) { futureEvents.push({ ...event }); } return; } // 转换重复规则为RRule可识别的格式 const rruleConfig = { ...event.rrule, byweekday: event.rrule.byweekday?.map(day => { // 将字符串/枚举转为RRule的Weekday实例(如'fr'转RRule.FR) if (typeof day === 'string') { return RRule[day.toUpperCase()]; } return RRule[day]; }) }; const rule = new RRule(rruleConfig); // 获取今天到截止日期之间的所有事件实例 const instances = rule.between(todayDate, new Date(event.rrule.until), true); instances.forEach(instance => { futureEvents.push({ ...event, start: instance.toISOString(), // 处理全天事件:去掉时间部分 ...(event.allDay ? { start: instance.toISOString().split('T')[0] } : {}) }); }); }); return futureEvents.sort((a, b) => new Date(a.start) - new Date(b.start)); };
- 在组件中调用:
const todayStr = new Date().toISOString().replace(/T.*$/, '') const [futureEvents, setFutureEvents] = useState([]); useEffect(() => { const events = getFutureEvents(INITIAL_EVENTS, todayStr); setFutureEvents(events); }, []);
注意事项
- 方法1依赖FullCalendar的API,会自动同步事件的增删改操作,适合有事件编辑需求的场景。
- 方法2适合需要完全掌控事件数据的场景,但需自行维护事件更新的同步逻辑。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

