Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 音频事件通过removeEventListener删除后仍会触发关闭事件_Javascript_Reactjs_Dom Events_Html5 Audio - Fatal编程技术网

Javascript 音频事件通过removeEventListener删除后仍会触发关闭事件

Javascript 音频事件通过removeEventListener删除后仍会触发关闭事件,javascript,reactjs,dom-events,html5-audio,Javascript,Reactjs,Dom Events,Html5 Audio,我的React组件中有以下两种生命周期方法,这是一个包含HTML元素的音频曲目: componentDidMount() { const {track} = this.props; this.refs.audio.src = track.getTrackUrl(); _.each(this.audioEvents, (callback, eventName) => { this.refs.audio.addEventListener(eventName, callba

我的React组件中有以下两种生命周期方法,这是一个包含HTML
元素的音频曲目:

componentDidMount() {
  const {track} = this.props;

  this.refs.audio.src = track.getTrackUrl();
  _.each(this.audioEvents, (callback, eventName) => {
    this.refs.audio.addEventListener(eventName, callback.bind(this));
  });
}

componentWillUnmount() {
  _.each(this.audioEvents, (callback, eventName) => {
    console.info(`Removed ${eventName} from ${this.props.track.name}`);
    this.refs.audio.removeEventListener(eventName, callback.bind(this));
  });
}
我可以从
控制台.info
调用中看到所有事件都已被删除,但在离开此特定路线/页面时仍会出现以下错误:

警告:设置状态(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是禁止操作。请检查未定义组件的代码

发生这种情况的原因是,即使在我删除了所有事件处理程序后,
pause
回调仍会被触发:

pause() {
  console.log('pause got fired for', this.props.track.name);
  this.setState({playing: false});
},

我错过了什么?我试图在组件卸载时进行一次很好的清理,但由于某种原因,当我离开页面(导致音频停止播放)时,
pause
的事件处理程序仍然会启动。

当您使用
.bind
时,您会创建一个新的函数实例。所以当你这样做的时候:

this.refs.audio.addEventListener(eventName, callback.bind(this));
您将无法再删除该事件侦听器,因为您没有保留对
callback.bind(this)
的引用。下面是您如何修复它的

componentDidMount() {
  const {track} = this.props;
  this.refs.audio.src = track.getTrackUrl();
  this.boundAudioEvents = _.mapValues(this.audioEvents, (callback, eventName) => {
    const boundEvent = callback.bind(this)
    this.refs.audio.addEventListener(eventName, boundEvent);
    return boundEvent;
  });
}

componentWillUnmount() {
  _.each(this.boundAudioEvents, (callback, eventName) => {
    console.info(`Removed ${eventName} from ${this.props.track.name}`);
    this.refs.audio.removeEventListener(eventName, callback);
  });
}

当您使用
.bind
时,将创建函数的新实例。所以当你这样做的时候:

this.refs.audio.addEventListener(eventName, callback.bind(this));
您将无法再删除该事件侦听器,因为您没有保留对
callback.bind(this)
的引用。下面是您如何修复它的

componentDidMount() {
  const {track} = this.props;
  this.refs.audio.src = track.getTrackUrl();
  this.boundAudioEvents = _.mapValues(this.audioEvents, (callback, eventName) => {
    const boundEvent = callback.bind(this)
    this.refs.audio.addEventListener(eventName, boundEvent);
    return boundEvent;
  });
}

componentWillUnmount() {
  _.each(this.boundAudioEvents, (callback, eventName) => {
    console.info(`Removed ${eventName} from ${this.props.track.name}`);
    this.refs.audio.removeEventListener(eventName, callback);
  });
}

太棒了!非常感谢。谢谢你,我已经为此奋斗了好几个小时。太棒了!非常感谢。谢谢你,我已经为此奋斗了好几个小时了。