React中FullCalendar点击事件/日期后重复请求JSON Feed如何避免?
解决FullCalendar点击事件触发重复请求和闪烁问题
问题根源
调用setSelectedEvent或setOpenEventModal更新组件状态时,父组件会触发重渲染,导致fetchEvents、handleEventClick等函数被重新创建。FullCalendar检测到eventSources内的events引用发生变化,就会重新发起事件数据请求,同时日历重绘引发闪烁问题。
解决方案
1. 用useCallback缓存事件相关函数
通过React.useCallback包裹fetchEvents、handleEventClick等函数,保证组件重渲染时这些函数的引用保持稳定:
import { useCallback, useState } from 'react'; // 缓存fetchEvents函数 const fetchEvents = useCallback((fetchInfo, successCallback, failureCallback) => { fetch('http://localhost/calendarEvents', { method: 'POST', body: JSON.stringify(fetchInfo), headers: { 'Content-Type': 'application/json', }, }) .then((res) => res.json()) .then((data) => { const parsedEvents = []; for (const event of data) { parsedEvents.push({ ...event, start: moment(event.startAt).toDate(), end: moment(event.endAt).toDate(), title: event.title }); } successCallback(parsedEvents); }) .catch((error) => { failureCallback(error); }); }, []); // 若函数依赖外部变量,需添加到依赖数组中 // 缓存handleEventClick const handleEventClick = useCallback((event) => { setSelectedEvent(event); setOpenEventModal(true); }, [setSelectedEvent, setOpenEventModal]); // 同理缓存handleDateClick const handleDateClick = useCallback((dateInfo) => { // 你的日期点击逻辑 }, []);
2. 用useMemo缓存eventSources配置
将eventSources数组通过useMemo缓存,避免每次渲染都生成新数组:
import { useMemo } from 'react'; const eventSources = useMemo(() => [ { events: fetchEvents, failure: function() { console.log('ERROR'); } }, ], [fetchEvents]);
之后在FullCalendar组件中使用这个缓存后的eventSources:
<FullCalendar ... eventClick={handleEventClick} dateClick={handleDateClick} eventSources={eventSources} ... />
3. 用React.memo包裹日历组件(可选)
如果父组件的其他状态更新也会触发日历重绘,可以用React.memo包裹当前日历组件,减少不必要的重渲染:
const CalendarComponent = React.memo(() => { // 你的日历组件逻辑 return <FullCalendar ... />; });
原理说明
useCallback确保函数引用在组件重渲染时不发生变化,FullCalendar不会因events函数变更而重复请求数据。useMemo缓存eventSources数组,避免每次渲染都创建新数组触发FullCalendar重新解析数据源。React.memo通过浅比较组件的props和state,仅在必要时触发重渲染,进一步降低不必要的日历重绘。
内容的提问来源于stack exchange,提问作者newtel
相关产品推荐
相关产品推荐

