From aa2e2bc42449ce82632fd6434a9ab5fa0b03c6c1 Mon Sep 17 00:00:00 2001 From: talksik Date: Thu, 19 Mar 2026 12:46:32 -0700 Subject: [PATCH] fix: navigate during state change is invalid with react router --- js/src/features/particles/stream-view.tsx | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/js/src/features/particles/stream-view.tsx b/js/src/features/particles/stream-view.tsx index 5d973e4..fb7a293 100644 --- a/js/src/features/particles/stream-view.tsx +++ b/js/src/features/particles/stream-view.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, useReducer, useRef } from "react"; +import { useState, useEffect, useEffectEvent, useCallback, useReducer, useRef } from "react"; import { useNavigate } from "react-router-dom"; import { useAuthStore } from "@/stores/auth-store"; import type { Particle } from "@/api/types"; @@ -102,6 +102,10 @@ function useExitCountdown( ) { const [exitProgress, setExitProgress] = useState(null); + const handleExit = useEffectEvent(() => { + onExit(); + }); + // Start/cancel countdown based on playback status useEffect(() => { if (status === "ended") { @@ -119,16 +123,19 @@ function useExitCountdown( setExitProgress((prev) => { if (prev === null) return null; const next = prev + EXIT_TICK_MS / EXIT_DELAY_MS; - if (next >= 1) { - onExit(); - return 1; - } - return next; + return next >= 1 ? 1 : next; }); }, EXIT_TICK_MS); return () => clearInterval(interval); - }, [exitProgress !== null, composeActive, onExit]); + }, [exitProgress !== null, composeActive]); + + // Navigate once countdown completes + useEffect(() => { + if (exitProgress !== null && exitProgress >= 1) { + handleExit(); + } + }, [exitProgress]); return exitProgress; }