Imagine you’re reading a long article online. Instead of having to click “Next Page” every time you reach the bottom, the page just keeps loading more content as you scroll down. This is called infinite scrolling.
Let’s see how to do it in React:
import React, { useState, useEffect } from 'react';
const InfiniteScrollList = () => {
const [items, setItems] = useState([]); // List of items
const [page, setPage] = useState(1); // Tracks the current page
const [loading, setLoading] = useState(false); // Loading state
const [error, setError] = useState(null); // Error state for handling fetch errors
// Fetch more items whenever the page changes
useEffect(() => {
fetchMoreItems();
}, [page]);
const fetchMoreItems = async () => {
setLoading(true);
setError(null); // Reset error state before new fetch
try {
const newItems = await fakeApiCall(page);
setItems(prevItems => [...prevItems, ...newItems]);
} catch (err) {
setError('Error fetching items');
} finally {
setLoading(false); // Ensure loading is reset after fetch attempt
}
};
// Handle scroll to detect if the user has reached the bottom
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop >=
document.documentElement.offsetHeight - 50 &&
!loading
) {
setPage(prevPage => prevPage + 1); // Load the next page
}
};
// Attach the scroll event listener when the component mounts
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll); // Cleanup on unmount
}, []);
return (
<div>
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
{loading && <p>Loading more, please wait...</p>}
{error && <p style={{ color: 'red' }}>{error}</p>} {/* Display error if any */}
</div>
);
};
// Simulated API call (returns 10 new items per page)
const fakeApiCall = page => {
return new Promise(resolve => {
setTimeout(() => {
const newItems = Array.from({ length: 10 }, (_, index) => ({
id: page * 10 + index,
name: `Item ${page * 10 + index}`,
}));
resolve(newItems);
}, 1000);
});
};
export default InfiniteScrollList;
Related Question : Implement role-based access control in a full-stack application