From ce46d3b5f7e9745e3f57fa0920ef3b3d193b46e9 Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 5 Mar 2026 13:54:15 +0800 Subject: [PATCH] fix(music-player): fix repeat button not working due to stale closure Problem: - Tombol repeat tidak berfungsi saat lagu selesai - Event listener 'ended' menggunakan variabel state 'isRepeat' dari closure yang lama - Meskipun state sudah di-toggle, event listener masih menggunakan nilai lama Solution: - Tambahkan isRepeatRef untuk menyimpan nilai terbaru dari isRepeat - Sync ref dengan state menggunakan useEffect - Gunakan isRepeatRef.current di event listener 'ended' - Remove isRepeat dari dependency array useEffect Files changed: - src/app/context/MusicContext.tsx: Add isRepeatRef and sync with state This ensures the repeat functionality works correctly when the song ends. Co-authored-by: Qwen-Coder --- src/app/context/MusicContext.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/app/context/MusicContext.tsx b/src/app/context/MusicContext.tsx index 60119836..19020151 100644 --- a/src/app/context/MusicContext.tsx +++ b/src/app/context/MusicContext.tsx @@ -82,6 +82,12 @@ export function MusicProvider({ children }: { children: ReactNode }) { const audioRef = useRef(null); const isSeekingRef = useRef(false); const animationFrameRef = useRef(null); + const isRepeatRef = useRef(false); // Ref untuk avoid stale closure + + // Sync ref dengan state + useEffect(() => { + isRepeatRef.current = isRepeat; + }, [isRepeat]); // Load musik data const loadMusikData = useCallback(async () => { @@ -111,7 +117,8 @@ export function MusicProvider({ children }: { children: ReactNode }) { }); audioRef.current.addEventListener('ended', () => { - if (isRepeat) { + // Gunakan ref untuk avoid stale closure + if (isRepeatRef.current) { audioRef.current!.currentTime = 0; audioRef.current!.play(); } else { @@ -132,7 +139,7 @@ export function MusicProvider({ children }: { children: ReactNode }) { } }; // eslint-disable-next-line react-hooks/exhaustive-deps -- playNext is intentionally not in deps to avoid circular dependency - }, [loadMusikData, isRepeat]); + }, [loadMusikData]); // Remove isRepeat dari deps karena sudah pakai ref // Update time with requestAnimationFrame for smooth progress const updateTime = useCallback(() => {