Dragging external events generates duplicates on calendar
See original GitHub issueIMPORTANT PREMISE:
I don’t understand if is a duplicate of this, in case delete the issue:
https://github.com/fullcalendar/fullcalendar/issues/7067
DESCRIPTION OF BUG
When dragging an external event to the calendar, one or more duplicates of the event are generated.
STEP TO REPRODUCE (WITH SAMPLE CODE)
I have a root component called PageCalendar. This component contains a list of draggable events and the calendar.
This is my event list:
// EventList.js
const EventList = (props) => {
useEffect(() => {
let draggableEl = document.getElementById("external-events");
new Draggable(draggableEl, {
itemSelector: ".fc-event",
eventData: function(eventEl) {
let id = eventEl.dataset.id;
let title = eventEl.getAttribute("title");
let color = eventEl.dataset.color;
let custom = eventEl.dataset.custom;
return {
id: id,
title: title,
color: color,
custom: custom,
create: true
};
}
});
});
// other stuff
And this is the calendar (notice that I passed events and event handling functions from the root component via props):
// Calendar.js
const Calendar = (props) => {
// other stuff
return (
<>
<FullCalendar
locale={itLocale}
plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
headerToolbar={{
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
}}
initialView='dayGridMonth'
editable={true}
selectable={true}
selectMirror={true}
dayMaxEvents={true}
weekends={props.weekendsVisible}
events={props.events}
droppable={true}
eventContent={renderEventContent}
eventClick={handleEventClick}
eventReceive={props.handleEventReceive}
/>
</>
);
};
export default Calendar;
And finally, this is my root component:
// PageCalendar.js
const PageCalendar = () => {
// initial state
const [state, setState] = useState({
weekendsVisible: true,
calendarEvents: getEvents(),
externalEvents: externalEvents(),
filterEvents: {
cat: null,
id: null
}
});
const handleEventReceive = (eventInfo) => {
const newEvent = {
id: eventInfo.draggedEl.getAttribute("data-id"),
title: eventInfo.draggedEl.getAttribute("title"),
color: eventInfo.draggedEl.getAttribute("data-color"),
start: eventInfo.date,
end: eventInfo.date,
custom: eventInfo.draggedEl.getAttribute("data-custom")
};
setState(state => {
return {
...state,
calendarEvents:state.calendarEvents.concat(newEvent)
};
});
};
return (
<>
<Header
addEvent={handleAddExternalEvent}
weekendsVisible={state.weekendsVisible}
filterEvents={handleFilterCalendarEvents}
weekendsToggle={handleWeekendsToggle}
/>
<CCard>
<CCardBody>
<CRow>
<CCol md="2">
<EventList
deleteEvent={handleDeleteEvent}
externalEvents={state.externalEvents}
filterEvents={handleFilterEvents}
/>
</CCol>
<CCol md="10">
<Calendar
events={state.calendarEvents}
handleEventReceive={handleEventReceive}
weekendsVisible={state.weekendsVisible}
/>
</CCol>
</CRow>
</CCardBody>
</CCard>
</>
);
};
export default PageCalendar;
Now, when you drag elements:
- for the first event dragged
handleEventReceive
function is called ONE time and ONE event is added to state and to the calendar; - for the second event dragged
handleEventReceive
function is called TWICE and TWO events are added to state and to the calendar; - for the third event dragged
handleEventReceive
function is called FOUR TIMES and FOUR events are added to state and to the calendar; - etc…
I already tried with created: false
in EventList
and using drop
instead of eventReceive
in Calendar
, but the result is the same.
I am sorry for bothering you, and I hope this can help someone.
Many thanks in advance 😃
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (3 by maintainers)
Top GitHub Comments
The problem is that your
useEffect
callback is being called whenever there is any state change to your root component, subsequently reinitializing theDraggable
without destroying it. These duplicate initializations on the same element result in multiple events being added each time.The solution is to make sure
new Draggable
is only called once per external element. Here is a solution that involves movinguseEffect
within a subcomponent,useRef
, andmemo
(to prevent unnecessary rerendering).https://codesandbox.io/s/fullcalendar-react-draggable-forked-ehr0h?file=/src/App.js
Thanks for the demo, it does seem like a bug, liekly related to the issue you mentioned but I’m not sure it’s a duplicate.