React中Wavesurfer 2.0事件实现问题求助
解决React中Wavesurfer 2.0事件回调调用setState报错的问题
嘿,这个问题我之前也碰到过!确实和this的上下文绑定有关——当你在Wavesurfer的事件回调里直接调用this.setState时,这里的this已经不是你的React组件实例了(而是指向Wavesurfer实例,严格模式下会变成undefined),所以才会抛出TypeError: Cannot read property 'setState' of undefined的错误。下面给你几个实用的解决办法:
方法1:用箭头函数自动继承上下文
箭头函数会自动沿用外部作用域的this(也就是你的React组件实例),这样就能正常调用setState了,写法也最简洁:
class AudioPlayer extends React.Component { componentDidMount() { this.wavesurfer = WaveSurfer.create({ container: this.audioContainer, // 你的其他配置项 }); // 箭头函数作为回调,this自动指向组件实例 this.wavesurfer.on('finish', () => { console.log('音频播放结束'); this.setState({ isPlaying: false }); }); } render() { return <div ref={el => this.audioContainer = el}></div>; } }
方法2:提前绑定this到组件实例
你可以在构造函数里把回调函数的this绑定到组件实例,或者在绑定事件时直接用bind:
方式A:构造函数内绑定(推荐,性能更优)
class AudioPlayer extends React.Component { constructor(props) { super(props); this.state = { isPlaying: false }; // 把回调的this绑定到组件实例 this.handleAudioFinish = this.handleAudioFinish.bind(this); } componentDidMount() { this.wavesurfer = WaveSurfer.create({ container: this.audioContainer, // 你的其他配置项 }); this.wavesurfer.on('finish', this.handleAudioFinish); } handleAudioFinish() { console.log('音频播放结束'); this.setState({ isPlaying: false }); } render() { return <div ref={el => this.audioContainer = el}></div>; } }
方式B:绑定事件时直接bind
componentDidMount() { this.wavesurfer = WaveSurfer.create({ container: this.audioContainer, // 你的其他配置项 }); // 直接在绑定事件时把this绑定到组件实例 this.wavesurfer.on('finish', this.handleAudioFinish.bind(this)); } handleAudioFinish() { console.log('音频播放结束'); this.setState({ isPlaying: false }); }
方法3:保存组件this到变量
在componentDidMount里先把组件的this存到一个变量(比如that),然后在回调里用这个变量调用setState:
componentDidMount() { const that = this; // 先把组件实例的this存起来 this.wavesurfer = WaveSurfer.create({ container: this.audioContainer, // 你的其他配置项 }); this.wavesurfer.on('finish', function() { console.log('音频播放结束'); that.setState({ isPlaying: false }); // 用that代替this }); }
额外小贴士
记得在组件卸载时清理Wavesurfer的事件监听和实例,避免内存泄漏:
componentWillUnmount() { if (this.wavesurfer) { this.wavesurfer.off('finish'); // 移除事件监听 this.wavesurfer.destroy(); // 销毁Wavesurfer实例 } }
内容的提问来源于stack exchange,提问作者Rex Wesley Reyes
相关产品推荐
相关产品推荐

