我正在尝试确定提高 React 组件内 onScroll
事件监听器性能的最佳方法。我有一个简单的监听器,用于跟踪 scrollY
为了跟踪它(跨浏览器),我有以下内容:
handleScroll = (event) => {
let scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop)
}
现在,我需要确定用户是向上还是向下滚动。我希望实际的 event
对象会有某种标志,但我大多数看到人们建议跟踪之前的 scrollTop
并与每次迭代进行比较功能。
我想知道,每次滚动句柄运行时调用 this.setState({scrollY:scrollTop})
对性能有何影响?当我使用滚动条向下滚动页面时,我的事件处理程序将触发大约 50-70 次。我知道 React.Component.setState 确实有一些异步/批处理行为 - 并且调用它 50 次似乎过多。
因此,我没有调用 setState
,而是考虑在组件中存储一个全局变量
- 我认为更新单个变量 50 次的影响会较小。我也在考虑限制该功能,但是如果我希望它相对敏感并且不会错过滚动事件,我可以限制该功能吗?
这基本上就是我想要做的:
// Global Variable ...
let avoidNameCollidePrevScrollTop
class WatchMeScroll extends Component {
handleScroll = (event) => {
let scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop)
if (avoidNameCollidePrevScrollTop && scrollTop > avoidNameCollidePrevScrollTop && this.state.scrollDir !== 'Scrolling Down') {
this.setState({
scrollDir: 'Scrolling Down'
})
}
if (avoidNameCollidePrevScrollTop && scrollTop < avoidNameCollidePrevScrollTop && this.state.scrollDir !== 'Scrolling Up') {
this.setState({
scrollDir: 'Scrolling Up'
})
}
// { Handle UI changes by checking if user is scrolling Up/Down into different sections of the app using Ref.getBoundingClientRect() }
// Set ScrollTop position for next iteration of handleScroll - avoiding setState firing excessively
avoidNameCollidePrevScrollTop = scrollTop
}
}
最佳答案
是的! setState()
是一个异步操作,但在每次 setState
调用之后,您的组件都会重新渲染,并且最终在像滚动处理程序一样频繁调用时可能会出现性能问题。
理想情况下,如果更改变量与更新 DOM(更具体地说是虚拟 DOM)无关,那么它不应该保留为状态变量,而是可以创建类变量,例如
constructor(props){
super(props);
this.someVar = someDefaultValue;
并且可以使用 this.someVar
在组件内的任何位置访问此变量 someVar
。
关于javascript - REACT- 将需要经常更新的数据存储为全局变量而不是使用 setState() - 不推荐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52153906/