[英]React: How to add state changing event listeners in hooks?
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.
目前它工作正常,但我试图让 en 事件监听器在音频组件播放或不播放时切换 state 变量。
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.但是,如果用户使用键盘上的播放/暂停按钮进行切换,则“isPlaying”的 state 变量不会改变,除非我在
onplay
和onpause
事件侦听器上切换它。
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此处的代码沙盒: 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]这是破坏它的部分:[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. onended
事件运行良好.. 没有任何问题.. 但其他事件正在破坏体验。
setState
out of useEffect
setState
移出useEffect
Adding this method:添加此方法:
function togglePause() {
setState((state) => ({
...state,
isPlaying: state.audioPlayer ? !state.audioPlayer.paused : false,
}));
}
And updating the useEffect
并更新
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..一旦第一个
state.audioPlayer
ended
,事件侦听器不会转移到下一个音频组件,而通过没有在useEffect
中编写onplay
和onpause
侦听器,确实会重新创建onended
并且它可以工作。
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. onpause
事件由onended
隐式触发,导致多个 state 更改发生在同一事件中。
The codesandbox is now fully working. 代码沙盒现在可以正常工作了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.