0

我正在尝试在 React 中呈现大量数据。我知道我可以在这个用例中使用 react-window,但是想尝试一下我们是否可以使用 Intersection Observer API 实现类似的基于窗口的渲染。

我已经编写了这个组件来尝试相同的操作。但是在这里,我的组件正在渲染整个 10,000 个 div,即使它不在视口中,因为我正在迭代数据。如果元素不在类似于 react-window 的视口中,是否有任何方法可以防止渲染。先感谢您。

import React from 'react';
import './CustomVirtualizedList.css';
import faker from 'faker';

const generateFakeData = (() => {
    const data = [];
    for (let i = 0; i < 10000; i++) {
        data.push({ id: i, selected: false, label: faker.address.state() })
    }
    return () => data;
})();

function getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

const ListElement = (props) => {
    const [visible, setVisible] = React.useState(false);
    const {containerRef} = props;
    const elementRef = React.useRef();
    let intersectionObserver;

    const onVisibilityChange = ([entry]) => {
        setVisible(entry.isIntersecting)
    }

    React.useEffect(() => {
        console.log(props);
        intersectionObserver = new IntersectionObserver(onVisibilityChange, containerRef.current);
        intersectionObserver.observe(elementRef.current);
        return () => {
            intersectionObserver.disconnect()
        }
    }, [])

    return <div
        ref={elementRef}
        style={{ backgroundColor: getRandomColor() }}
        className="listElement">
        {visible ? 'I am visible' : 'I am not visible'}
    </div>
}

export const ListContainer = () => {
    const containerRef = React.useRef();
    const [data, setData] = React.useState(generateFakeData())

    return (
        <div className="listContainer">
            {data.map(val => {
                return <ListElement containerRef={containerRef} {...val} />
            })}
        </div>
    );
};

4

0 回答 0