Reputation: 1884
I am working on a little music component that I found online. Currently now it works fine, but I have tried to make en event listener that toggles a state variable whenever the audio component is playing or no.
Currently I toggle this variable manually, whenever the user clicks a button. But if the user is toggling using play/pause buttons on the keyboard, the state variable for "isPlaying" doesn't change unless I toggle it on the onplay
and onpause
event listeners.
Unfortunately, this breaks the entire functionality for the hook, and I am nor sure what to do in order to solve it..
Codesandbox here: https://codesandbox.io/s/freaking-music-player-ldxde?file=/src/hooks/useMusicPlayer.js
This is the part that breaks it: [src/hooks/useMusicPlayer.js - line: 7]
useEffect(() => {
if (state.audioPlayer) {
// => Applying these event listeners **** up everything!
// console.log(state.audioPlayer);
// state.audioPlayer.onplay = (event) => {
// setState((state) => ({ ...state, isPlaying: true }));
// };
// state.audioPlayer.onpause = (event) => {
// setState((state) => ({ ...state, isPlaying: false }));
// };
state.audioPlayer.onended = event => {
playNextTrack();
};
}
}, [state, playNextTrack]);
The onended
event works fine.. No trouble whatsoever.. But the other ones are messing up the experience.
setState
out of useEffect
Adding this method:
function togglePause() {
setState((state) => ({
...state,
isPlaying: state.audioPlayer ? !state.audioPlayer.paused : false,
}));
}
And updating the useEffect
useEffect(() => {
if (state.audioPlayer) {
console.log(state.audioPlayer);
state.audioPlayer.onplay = (event: Event) => {
togglePause();
};
state.audioPlayer.onpause = (event: Event) => {
togglePause();
};
state.audioPlayer.onended = (event: Event) => {
playNextTrack();
};
}
}, [state, playNextTrack]);
This however still causes issues..
Clarification on the actual issue itself
Once the first state.audioPlayer
has ended
, the event listeners aren't transferred to the next Audio Component, whereas by NOT having the onplay
and onpause
listeners written in useEffect
, the onended
is indeed created anew and it works..
Upvotes: 0
Views: 379
Reputation: 1884
There wasn't an actual issue with the code itself. It boils down to the various event handlers. The onpause
event is implicitly triggered by the onended
which caused multiple state changes to happen in the same event.
The codesandbox is now fully working.
Upvotes: 1