我正在尝试在 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>
);
};