From e5a6feb6f62b5c1f4cf5b7d2328aa5c9ba257562 Mon Sep 17 00:00:00 2001 From: mac-agent <91694179+mac-agent@users.noreply.github.com> Date: Sat, 4 Apr 2026 07:02:51 -0400 Subject: [PATCH] fix: clear stagger toast timers on unmount in AnnouncementToastProvider Stagger setTimeout calls inside the for loop were never cleared on component unmount, causing potential setState calls on unmounted components when the user navigates away before all toasts fire. Fixes #1094 --- .../announcements/AnnouncementToastProvider.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/surfsense_web/components/announcements/AnnouncementToastProvider.tsx b/surfsense_web/components/announcements/AnnouncementToastProvider.tsx index 6cb1b17e5..9095b84aa 100644 --- a/surfsense_web/components/announcements/AnnouncementToastProvider.tsx +++ b/surfsense_web/components/announcements/AnnouncementToastProvider.tsx @@ -65,6 +65,8 @@ export function AnnouncementToastProvider() { if (hasChecked.current) return; hasChecked.current = true; + const staggerTimers: ReturnType[] = []; + const timer = setTimeout(() => { const authed = isAuthenticated(); const active = getActiveAnnouncements(announcements, authed); @@ -74,11 +76,18 @@ export function AnnouncementToastProvider() { for (let i = 0; i < importantUntoasted.length; i++) { const announcement = importantUntoasted[i]; - setTimeout(() => showAnnouncementToast(announcement), i * 800); + const staggerId = setTimeout( + () => showAnnouncementToast(announcement), + i * 800 + ); + staggerTimers.push(staggerId); } }, 1500); - return () => clearTimeout(timer); + return () => { + clearTimeout(timer); + staggerTimers.forEach((id) => clearTimeout(id)); + }; }, []); return null;