54 lines
1.4 KiB
React
54 lines
1.4 KiB
React
import { useEffect, useRef, useState } from 'react';
|
|
import styles from './App.css';
|
|
|
|
const InfiniteList = () => {
|
|
const [items, setItems] = useState([...Array(20).keys()]); // Initial data
|
|
const loaderRef = useRef(null);
|
|
|
|
const loadMore = () => {
|
|
setItems((prev) => [...prev, ...Array(10).keys()].map((_, i) => prev.length + i));
|
|
};
|
|
|
|
useEffect(() => {
|
|
const observer = new IntersectionObserver((entries) => {
|
|
if (entries[0].isIntersecting) {
|
|
loadMore(); // Load next batch when the loader is seen
|
|
}
|
|
});
|
|
|
|
if (loaderRef.current) observer.observe(loaderRef.current);
|
|
return () => observer.disconnect();
|
|
}, []);
|
|
|
|
return (
|
|
<ul>
|
|
{items.map(item => <li key={item} className={ styles.item }>Item {item}</li>)}
|
|
<div ref={loaderRef}>Loading more...</div>
|
|
</ul>
|
|
);
|
|
};
|
|
|
|
function App() {
|
|
const generatedBigDataSet = () => {
|
|
return Array.from({ length: 100 }, (_, index) => ({
|
|
id: index,
|
|
name: `Элемент № ${index}`,
|
|
value: Math.floor(Math.random() * 1000)
|
|
}))
|
|
}
|
|
const [data] = useState(generatedBigDataSet);
|
|
|
|
return (
|
|
<>
|
|
<div>
|
|
<h2>Визуализация большого списка</h2>
|
|
<div className={ styles.container }>
|
|
<InfiniteList />
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default App
|