import React, { useState, useEffect } from 'react';
const InfiniteScroll = ({ items }) => {
const [visibleItems, setVisibleItems] = useState([]);
const [itemsToShow, setItemsToShow] = useState(6);
useEffect(() => {
// Изначальная загрузка элементов
setVisibleItems(items.slice(0, itemsToShow));
}, [items, itemsToShow]);
const handleScroll = () => {
if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return;
loadMoreItems();
};
const loadMoreItems = () => {
setItemsToShow(prevCount => prevCount + 2);
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return (
{visibleItems.map((item, index) => (
{item}
))}
);
};
export default InfiniteScroll;
Используйте компонент в вашем приложении: import React from 'react';
import InfiniteScroll from './InfiniteScroll';
const App = () => {
const items = Array.from({ length: 100 }, (_, i) => `Card ${i + 1}`);
return (
Infinite Scroll Example
);
};
export default App;
CSS для стилизации карточек (по желанию): .card {
border: 1px solid #ccc;
padding: 20px;
margin: 10px 0;
background: #f9f9f9;
}
В этом коде: import React, { useState, useEffect, useRef } from 'react';
function App() {
const [cards, setCards] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
const observer = useRef(null);
useEffect(() => {
// Получение начальных 6 карточек
fetchCards(6);
}, []);
// Получение карточек с сервера
const fetchCards = async (count) => {
setIsLoading(true);
try {
// Запрос на получение карточек
const response = await fetch('сайтик');
const data = await response.json();
// Добавление новых карточек в массив
setCards((prevCards) => [...prevCards, ...data.slice(0, count)]);
setHasMore(data.length > prevCards.length);
} catch (error) {
console.error('Error fetching cards:', error);
} finally {
setIsLoading(false);
}
};
// Наблюдение за скроллом
useEffect(() => {
const handleObserver = (entries) => {
if (entries[0].isIntersecting && hasMore) {
fetchCards(2);
}
};
const options = {
root: null,
rootMargin: '200px',
threshold: 1.0,
};
// Создание наблюдателя
observer.current = new IntersectionObserver(handleObserver, options);
if (observer.current) {
observer.current.observe(document.querySelector('.observer'));
}
// Очистка наблюдателя при размонтировании компонента
return () => observer.current.disconnect();
}, [hasMore]);
return (
{/* Отрисовка карточек */}
{cards.map((card, index) => (
{/* Содержимое карточки */}
))}
{/* Элемент для наблюдения */}
{/* Загрузка */}
{isLoading && Загрузка...}
);
}
export default App;
import { useEffect, useState } from 'react'
const [ posts, setPosts ] = useState([]) //Карточки ну или посты
const [ pageLimit, setPageLimit ] = useState(6) //Изначальное количество постов
useEffect(() => {
const fetchData = async (url) => {
const response = await fetch(url)
const data = await response.json()
const finalData = data.slice(0, pageLimit)
setPosts(finalData)
}
fetchData('link-here')
}, [pageLimit])
window.addEventListener('scroll', () => {
if ((window.scrollY + window.innerHeight) >= document.body.offsetHeight) {
setPageLimit(prev => prev += 2) //Увеличиваем количество постов на 2 когда скролл достигает конца страницы
}
})