我在听窗户"滚动"我的一个组件中的事件。但是,当组件卸载时,不会删除滚动事件侦听器。
在卸载组件后发生滚动事件时会产生以下错误:
warning.js:36警告:setState(...):只能更新已安装或 安装组件。这通常意味着你在一个上调用了setState() 未安装的组件。这是一个无操作。请检查代码 TopNavDesktop组件。
如何正确删除此事件侦听器?
示例代码:
class NavBar extends Component {
constructor() {
super();
this.state = {
distanceScrolled: null
}
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll.bind(this));
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll.bind(this));
}
handleScroll(e){
const distanceScrolled = e.srcElement.body.scrollTop;
this.setState({ distanceScrolled: distanceScrolled });
}
render { ... }
}
答案 0 :(得分:8)
删除侦听器时,您将创建一个新的函数引用。
someFn.bind(this) === someFn.bind(this)
评估为false。
相反,请将该函数保存在构造函数中并使用该引用:
class NavBar extends Component {
constructor() {
super();
this.state = {
distanceScrolled: null
}
this.scrollFn = this.handleScroll.bind(this);
}
componentDidMount() {
window.addEventListener('scroll', this.scrollFn);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.scrollFn);
}
handleScroll(e){
const distanceScrolled = e.srcElement.body.scrollTop;
this.setState({ distanceScrolled: distanceScrolled });
}
render { ... }
}
答案 1 :(得分:2)
你应该这样做:
componentDidMount() {
this.listener = this.handleScroll.bind(this);
window.addEventListener('scroll', this.listener);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.listener);
}
通过在this.handleScroll.bind(this)
中调用第二次componentWillUnmount
来创建新函数,而不是传递之前的函数。