React:如何在钩子中添加状态更改事件监听器?

时间:2020-06-27 15:51:15

标签: javascript reactjs

我正在研究在网上找到的一个音乐小部件。目前,它可以正常工作,但是我尝试使事件监听器在音频组件播放或不播放时切换状态变量。

当前,每当用户单击按钮时,我都会手动切换此变量。但是,如果用户正在使用键盘上的播放/暂停按钮进行切换,则除非在onplayonpause事件监听器上进行切换,否则“ isPlaying”的状态变量不会改变。

不幸的是,这破坏了钩子的全部功能,我也不知道该怎么做才能解决它。.

此处的Codesandbox: https://codesandbox.io/s/freaking-music-player-ldxde?file=/src/hooks/useMusicPlayer.js

这是破坏它的部分:[src / hooks / useMusicPlayer.js-行: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]);

onended事件工作正常。.没有任何问题。.但是其他事件使体验混乱。

更新:将setStateuseEffect中移出

添加此方法:

  function togglePause() {
    setState((state) => ({
      ...state,
      isPlaying: state.audioPlayer ? !state.audioPlayer.paused : false,
    }));
  }

并更新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]);

但这仍然会引起问题。

对实际问题的澄清

第一个state.audioPlayer具有ended之后,事件监听器不会转移到下一个音频组件,而具有onplay和{ {1}}用onpause编写的侦听器,useEffect确实是重新创建的并且可以工作。.

1 个答案:

答案 0 :(得分:0)

代码本身没有实际问题。归结为各种事件处理程序。 onpauseonended隐式触发,导致同一事件中发生多个状态更改。

codesandbox现在可以正常工作。