From b6c94cfe73d65b8cd425efacccc4c8d70fca896b Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:26:10 +0300 Subject: [PATCH] B: Fix potential memory leaks --- .../frontend/src/features/home/home-page.tsx | 14 +++++++++----- .../src/hooks/use-browser-navigation.ts | 18 +++++++++++++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/rsconcept/frontend/src/features/home/home-page.tsx b/rsconcept/frontend/src/features/home/home-page.tsx index 13dc0b31..de084798 100644 --- a/rsconcept/frontend/src/features/home/home-page.tsx +++ b/rsconcept/frontend/src/features/home/home-page.tsx @@ -1,5 +1,7 @@ 'use client'; +import { useEffect } from 'react'; + import { urls, useConceptNavigation } from '@/app'; import { useAuthSuspense } from '@/features/auth'; @@ -9,12 +11,14 @@ export function HomePage() { const router = useConceptNavigation(); const { isAnonymous } = useAuthSuspense(); - if (isAnonymous) { + useEffect(() => { // Note: Timeout is needed to let router initialize - setTimeout(() => router.replace({ path: urls.login }), PARAMETER.minimalTimeout); - } else { - setTimeout(() => router.replace({ path: urls.library }), PARAMETER.minimalTimeout); - } + const timeoutId = setTimeout(() => { + router.replace({ path: isAnonymous ? urls.login : urls.library }); + }, PARAMETER.minimalTimeout); + + return () => clearTimeout(timeoutId); + }, [router, isAnonymous]); return null; } diff --git a/rsconcept/frontend/src/hooks/use-browser-navigation.ts b/rsconcept/frontend/src/hooks/use-browser-navigation.ts index 59ccf925..413b2078 100644 --- a/rsconcept/frontend/src/hooks/use-browser-navigation.ts +++ b/rsconcept/frontend/src/hooks/use-browser-navigation.ts @@ -9,16 +9,28 @@ export function useBrowserNavigation() { const end = useAppTransitionStore(state => state.endNavigation); useEffect(() => { + let timeoutId: ReturnType | null = null; + const onPopState = () => { start(); + if (timeoutId) { + clearTimeout(timeoutId); + } + // Fallback to end the navigation in case route completes with cache - setTimeout(() => { + timeoutId = setTimeout(() => { end(); - }, DELAY_CACHE_CHECK); // or cancel after Suspense/loader finishes + timeoutId = null; + }, DELAY_CACHE_CHECK); }; window.addEventListener('popstate', onPopState); - return () => window.removeEventListener('popstate', onPopState); + return () => { + window.removeEventListener('popstate', onPopState); + if (timeoutId) { + clearTimeout(timeoutId); + } + }; }, [start, end]); }