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 <qwen-coder@alibabacloud.com>
This commit is contained in:
2026-03-05 13:54:15 +08:00
parent 144ac37e12
commit ce46d3b5f7

View File

@@ -82,6 +82,12 @@ export function MusicProvider({ children }: { children: ReactNode }) {
const audioRef = useRef<HTMLAudioElement | null>(null);
const isSeekingRef = useRef(false);
const animationFrameRef = useRef<number | null>(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(() => {