Skip to content

[scheduler] Listener leak: MoreEventsPopover never unsubscribes its close handler #22755

Description

@rita-codes

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    scope: schedulerChanges related to the scheduler.type: enhancementIt’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions