Skip to content

Clear stagger toast timers on unmount in AnnouncementToastProvider #1094

@MODSetter

Description

@MODSetter

Description

In AnnouncementToastProvider, the useEffect cleanup only clears the outer 1500ms timer. The inner stagger timers (i * 800 per announcement) are never cleared. If the root layout unmounts during the stagger, late toast calls fire after cleanup.

File to change

  • surfsense_web/components/announcements/AnnouncementToastProvider.tsx (lines 64-82)

Current code

useEffect(() => {
  if (hasChecked.current) return;
  hasChecked.current = true;

  const timer = setTimeout(() => {
    // ...
    for (let i = 0; i < importantUntoasted.length; i++) {
      const announcement = importantUntoasted[i];
      setTimeout(() => showAnnouncementToast(announcement), i * 800); // Not tracked!
    }
  }, 1500);

  return () => clearTimeout(timer); // Only clears outer timer
}, []);

What to do

Track inner timer IDs and clear all in cleanup:

useEffect(() => {
  if (hasChecked.current) return;
  hasChecked.current = true;
  const timerIds: ReturnType<typeof setTimeout>[] = [];

  const outerTimer = setTimeout(() => {
    // ...
    for (let i = 0; i < importantUntoasted.length; i++) {
      const announcement = importantUntoasted[i];
      timerIds.push(
        setTimeout(() => showAnnouncementToast(announcement), i * 800)
      );
    }
  }, 1500);

  return () => {
    clearTimeout(outerTimer);
    timerIds.forEach(clearTimeout);
  };
}, []);

Acceptance criteria

  • All stagger timers are cleared on cleanup
  • Announcement toasts still appear with staggered timing on normal flow

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions