通过 removeEventListener 删除后音频事件仍然触发事件
Audio event still firing off event after removed via removeEventListener
我的 React 组件中有以下两个生命周期方法,它是一个包含 HTML <audio>
元素的音轨:
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));
});
}
我可以从 console.info
调用中看到所有事件都被删除了,但是当我离开这个特定的 route/page:
时,我仍然收到以下错误
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.
发生这种情况是因为 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);
});
}
我的 React 组件中有以下两个生命周期方法,它是一个包含 HTML <audio>
元素的音轨:
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));
});
}
我可以从 console.info
调用中看到所有事件都被删除了,但是当我离开这个特定的 route/page:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.
发生这种情况是因为 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);
});
}