【问题标题】:How to detect hidden component in React如何检测 React 中的隐藏组件
【发布时间】:2018-01-22 18:07:24
【问题描述】:

简而言之,

我有一个无限滚动列表,为每个 Item 5 PureComponent 渲染。

我的想法是,仅在项目可见时才渲染 5 PureComponent。

问题是,

如何检测Item组件是否对用户可见?

【问题讨论】:

  • 你的意思是在视口中不可见的组件不会成为 DOM 的一部分?
  • 嗯,Item 组件仍然会在这里,但不会包含在其中的其他 5 个 PureComponent。

标签: javascript performance reactjs rendering


【解决方案1】:

最简单的解决方案:

scrollPositioncontainerSize 添加到this.state

render()中的容器中创建ref

<div ref={cont => { this.scrollContainer = cont; }} />

componentDidMount()订阅scroll事件

this.scrollContainer.addEventListener('scroll', this.handleScroll)

componentWillUnmount()退订

this.scrollContainer.removeEventListener('scroll', this.handleScroll)

你的handleScroll应该看起来像

handleScroll (e) {
    const { target: { scrollTop, clientHeight } } = e;
    this.setState(state => ({...state, scrollPosition: scrollTop, containerSize: clientHeight}))
}

然后在您的渲染函数中检查应该显示哪个元素并渲染正确的元素 numOfElementsToRender = state.containerSize / elementSizefirstElementIndex = state.scrollPosition / elementSize - 1

当您拥有所有这些时,只需呈现您的元素列表并根据元素的index 应用过滤器,或者您想要对它们进行排序

您需要处理所有边缘情况并添加 bufor 以实现平滑滚动(高度的 20% 应该没问题)

【讨论】:

    【解决方案2】:

    您可以将 IntersectionObserver API 与 polyfill 一起使用(它是 chrome 61+)。这是寻找交叉点的一种更高效的方式(在新浏览器中),在其他情况下,它会回退到 piro 的答案。它们还允许您指定交集变为真的阈值。看看这个:

    https://github.com/researchgate/react-intersection-observer

    import React from 'react';
    import 'intersection-observer'; // optional polyfill
    import Observer from '@researchgate/react-intersection-observer';
    
    class ExampleComponent extends React.Component {
        handleIntersection(event) {
            console.log(event.isIntersecting); // true if it gets cut off
        }
    
        render() {
            const options = {
                onChange: this.handleIntersection,
                root: "#scrolling-container",
                rootMargin: "0% 0% -25%"
            };
    
            return (
                <div id="scrolling-container" style={{ overflow: 'scroll', height: 100 }}>
                    <Observer {...options}>
                        <div>
                            I am the target element
                        </div>
                    </Observer>
                </div>
            );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-10-07
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-29
      相关资源
      最近更新 更多