如何解决React 生命周期 vs 窗口事件竞争条件
我希望有人可以阐明 React 的状态和事件处理程序如何与直接在 window 对象本身上设置的事件处理程序交互(在 React 生命周期之外)。例如,在以下代码示例中,我们直接在 window
对象上设置了一个事件处理程序。现在我对浏览器如何处理窗口事件的理解是,当事件触发时,浏览器会将回调函数放入事件循环的队列中。
在这种情况下,处理程序直接设置在窗口上,事件处理程序函数进入事件循环的队列发生在 React 组件生命周期之外/独立于 React 组件生命周期。但是,事件处理程序调用 React 的 setState
异步更新组件状态。更新是异步进行的,因此 React 可以更有效地将状态更改一起批处理,从而避免过于频繁地重新渲染。
import { Component,createRef } from "react";
class GridView extends Component {
constructor(props) {
super(props);
this.state = {
hasScrolled: false
}
this.handleScrollEvent = this.handleScrollEvent.bind(this);
}
componentDidMount() {
window.addEventListener("scroll",this.handleScrollEvent);
}
componentWillUnmount() {
window.removeEventListener("scroll",this.handleScrollEvent);
}
handleScrollEvent() {
this.setState({hasScrolled: true})
}
render() {
return <div > ... some scrollable content </div>
}
}
我的问题是:我可以确定在第一次触发 handleScrollEvent
回调时,在页面最初滚动后,组件的 hasScrolled
状态值将在下一次触发 true
之前更新为 handleScrollEvent
?
我的理解是 React 的 setState
的异步性质使得我无法 100% 确定 何时 状态将根据触发的事件更新绑定到 window
。我的理解正确吗?
更进一步,假设我要通过在组件的 onScroll
方法中添加一个 render
回调,将滚动事件处理程序移动到 React 组件生命周期中,如下所示。我的假设是,即使滚动事件处理程序和状态更新都在 React 中管理,但我仍然无法确定回调和状态更改的确切顺序,因为 React 中的事件处理程序是异步和批处理的,就像 {{1 }}。
setState
那么,你真的能确定 React 中与事件处理程序相关的状态更新的顺序吗?如果答案是否定的,您永远无法 100% 确定,那么鉴于实例变量是同步更新的,事件处理程序内部的逻辑是否应该依赖于组件的实例变量而不是组件的状态?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。