javascript - 使用窗口事件侦听器时反应更新警告
问题描述
当我离开路由组件时,我收到以下警告:
警告:只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState、replaceState 或 forceUpdate。这是一个无操作。
添加滚动事件侦听器后,警告开始出现。如何防止出现此警告?我只绑定了一次事件方法。事件监听器在 componentDidMount 中添加,在 componentWillUnmount 中移除。
class DashboardRoute extends React.Component {
constructor (props) {
super(props)
this.handleScroll = this.handleScroll.bind(this);
this.state = {
scrolled: false
};
}
componentDidMount () {
window.addEventListener('scroll', throttle(this.handleScroll, 250));
}
componentWillUnmount () {
window.removeEventListener('scroll', throttle(this.handleScroll, 250));
}
handleScroll (e) {
let scrolled = (window.scrollY > 0);
if (scrolled !== this.state.scrolled) {
this.setState({scrolled: scrolled});
}
}
render () {
return (
<div>
<!-- Component code -->
</div>
);
}
}
解决方案
由于滚动事件处理程序可能会延迟多达 250 毫秒,因此您的组件可能会在它被调用之前被卸载。这取决于在DashboardRoute
整个应用程序中的使用方式。
您可以使用一个名为 eg 的实例变量_mounted
来跟踪组件是否实际上仍然挂载,并在使用之前在滚动处理程序中使用它setState
。
window.removeEventListener('scroll', throttle(this.handleScroll, 250))
也会尝试移除一个新创建的函数作为滚动监听器,所以创建的监听器window.addEventListener('scroll', throttle(this.handleScroll, 250))
不会被移除。您可以创建一次节流方法并引用它。
例子
class DashboardRoute extends React.Component {
_mounted = true;
state = {
scrolled: false
};
componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount() {
this._mounted = false;
window.removeEventListener("scroll", this.handleScroll);
}
handleScroll = throttle(e => {
let scrolled = window.scrollY > 0;
if (this._mounted && scrolled !== this.state.scrolled) {
this.setState({ scrolled: scrolled });
}
}, 250);
render() {
return <div>{/* ... */}</div>;
}
}
推荐阅读
- ios - AVRoutePickerView 不接受 overrideOutputAudioPort(.speaker) 对路由所做的更改
- c++ - 调用 Qt 的 setui 方法后是否应该检查空指针?
- flutter - 子小部件中的 setState()
- javascript - 在 Eclipse 中将 jquery 添加到我的“动态 Web 项目”中
- itext - Itext 7 - 梳状字段 - 填写表格
- javascript - 为什么组件内部的函数在 componentDidMount 之前执行?
- apache - cURL vs ab performance testing
- msbuild - 如何解压缩 zip 文件并从中导入 smth 作为构建的一部分?
- flutter - what is the sink in streamcontroller in flutter
- amazon-web-services - 有没有办法按需重新运行 AWS Security Hub CIS 基准?