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:
@@ -82,6 +82,12 @@ export function MusicProvider({ children }: { children: ReactNode }) {
|
|||||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||||
const isSeekingRef = useRef(false);
|
const isSeekingRef = useRef(false);
|
||||||
const animationFrameRef = useRef<number | null>(null);
|
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
|
// Load musik data
|
||||||
const loadMusikData = useCallback(async () => {
|
const loadMusikData = useCallback(async () => {
|
||||||
@@ -111,7 +117,8 @@ export function MusicProvider({ children }: { children: ReactNode }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
audioRef.current.addEventListener('ended', () => {
|
audioRef.current.addEventListener('ended', () => {
|
||||||
if (isRepeat) {
|
// Gunakan ref untuk avoid stale closure
|
||||||
|
if (isRepeatRef.current) {
|
||||||
audioRef.current!.currentTime = 0;
|
audioRef.current!.currentTime = 0;
|
||||||
audioRef.current!.play();
|
audioRef.current!.play();
|
||||||
} else {
|
} 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
|
// 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
|
// Update time with requestAnimationFrame for smooth progress
|
||||||
const updateTime = useCallback(() => {
|
const updateTime = useCallback(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user