Summary
In MoreEventsPopoverContent, the useEffect that subscribes a close handler never returns the unsubscribe function, so each time the "+N more" popover content mounts it adds a 'close' listener to the modal's EventManager that is never removed. Listeners (and their closures) accumulate for the lifetime of the calendar, and the EventManager max-listeners warning eventually fires.
Details
subscribeCloseHandler does return an unsubscribe:
// create-modal/createModal.tsx
const subscribeCloseHandler = (handler) => {
eventManager.current.on('close', handler);
return () => eventManager.current.removeListener('close', handler);
};
But the popover ignores it:
// more-events-popover/MoreEventsPopover.tsx
React.useEffect(() => {
subscribeCloseHandler(() => {
onClose();
});
// ❌ no cleanup returned
}, [subscribeCloseHandler, onClose]);
The "+N more" popover content mounts on each open (and unmounts on close), so every open leaks one 'close' listener.
Suggested fix
Return the unsubscribe from the effect:
React.useEffect(() => {
return subscribeCloseHandler(() => onClose());
}, [subscribeCloseHandler, onClose]);
Context
@mui/x-scheduler (master, pre-stable). Real leak with a trivial fix; low impact per open, hence Medium.
Summary
In
MoreEventsPopoverContent, theuseEffectthat subscribes a close handler never returns the unsubscribe function, so each time the "+N more" popover content mounts it adds a'close'listener to the modal'sEventManagerthat is never removed. Listeners (and their closures) accumulate for the lifetime of the calendar, and theEventManagermax-listeners warning eventually fires.Details
subscribeCloseHandlerdoes return an unsubscribe:But the popover ignores it:
The "+N more" popover content mounts on each open (and unmounts on close), so every open leaks one
'close'listener.Suggested fix
Return the unsubscribe from the effect:
Context
@mui/x-scheduler(master, pre-stable). Real leak with a trivial fix; low impact per open, hence Medium.