javascript - REACT- 将需要经常更新的数据存储为全局变量而不是使用 setState() - 不推荐?

标签 javascript reactjs performance scroll global-variables

我正在尝试确定提高 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/

相关文章:

javascript - 从 requirejs 优化中排除模板

javascript - 如何检查在输入字段中输入的值在AngularJS中是否已经可用

javascript - 如何在 GatsbyJS/ReactJS 中重复执行窗口函数?

Swift 4 字符串索引在处理大字符串时偏移太慢

javascript - 使用 array.push 进行正确编码

javascript - 如何使用jquery对表的每一行和每一列的值进行求和

javascript - 如何在 NextJS 13 中导入自定义谷歌字体?链接标签不起作用

javascript - 如何处理 React/Firebase 聊天应用程序中可见/不可见的聊天消息?

windows - 如何使用 Get-Counter 一次返回多个性能计数器?

ruby-on-rails - Rails,find_by().present 存在吗?比 where().exists 性能更高?