如何在React中检测隐藏的组件

时间:2018-01-22 18:07:24

标签: javascript performance reactjs rendering

简而言之,

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

我的想法是以某种方式,只有在项目可见时才渲染5 PureComponent。

问题是,

  

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

2 个答案:

答案 0 :(得分:1)

最简单的解决方案:

scrollPositioncontainerSize添加到this.state

ref

中为容器创建render()

<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上应用过滤器,或者你想要对它们进行排序

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

答案 1 :(得分:1)

您可以将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>
        );
    }
}