ARTICLE AD BOX
I'm using react-big-calendar (v1.19.4) with the drag-and-drop addon.
When I create an all-day event (rendered in the all-day row) and then drag it into the time grid area, the event starts flickering continuously during the drag operation.
Expected behavior
The event should smoothly move into the time grid without any flickering (similar to Google Calendar behavior).
Actual behavior
While dragging the all-day event into the time grid, the component repeatedly re-renders and visually flickers.
Environment
react: v18.3.1
react-big-calendar: v1.19.4
date-fns: v3.6.0
Below is the relevant implementation:
const handleDragStart = useCallback(({ event }: { event: CalendarEvent }) => { draggedEventRef.current = event.id; originalEventRef.current = { ...event }; }, []); const handleEventDrop = useCallback( ({ event, start, end, isAllDay }: EventInteractionArgs<CalendarEvent>) => { const startDate = new Date(start); const endDate = new Date(end); const wasAllDay = event.allDay === true; const hasSpecificTime = startDate.getHours() !== 0 || startDate.getMinutes() !== 0; if (wasAllDay && hasSpecificTime) { draggedEventRef.current = null; originalEventRef.current = null; return; } let newIsAllDay: boolean; if (wasAllDay) { newIsAllDay = true; } else if (hasSpecificTime) { newIsAllDay = false; } else if (isAllDay !== undefined) { newIsAllDay = isAllDay; } else { const isStartMidnight = startDate.getHours() === 0 && startDate.getMinutes() === 0; const isEndMidnight = endDate.getHours() === 0 && endDate.getMinutes() === 0; newIsAllDay = isStartMidnight && isEndMidnight && (endDate.getTime() - startDate.getTime()) % 86400000 === 0; } setEvents((prevEvents) => prevEvents.map((item) => item.id === event.id ? { ...item, start: startDate, end: endDate, allDay: newIsAllDay, } : item ) ); draggedEventRef.current = null; originalEventRef.current = null; }, [] ); const handleEventResize = useCallback( ({ event, start, end }: EventInteractionArgs<CalendarEvent>) => { if (event.allDay) return; setEvents((prevEvents) => prevEvents.map((item) => item.id === event.id ? { ...item, start: start as Date, end: end as Date } : item ) ); }, [] ); return ( <DnDCalendar localizer={localizer} events={events} onDragStart={handleDragStart} onEventDrop={handleEventDrop} onEventResize={handleEventResize} onSelectSlot={handleSelectSlot} onSelectEvent={handleSelectEvent} selectable resizable resizableAccessor={(event: CalendarEvent) => !event.allDay} draggableAccessor={(event: CalendarEvent) => event.allDay !== true} defaultView="week" views={["month", "week", "day"]} components={{ event: CustomEvent }} messages={{ next: t('calendar.next'), previous: t('calendar.previous'), today: t('calendar.today'), month: t('calendar.month'), week: t('calendar.week'), day: t('calendar.day'), agenda: t('calendar.agenda'), date: t('calendar.date'), time: t('calendar.time'), event: t('calendar.event'), noEventsInRange: t('calendar.noEventsInRange'), }} style={{ height: '80vh' }} /> );