The InfiniteScroll component is a reusable React component designed to provide infinite scrolling functionality in web applications. It leverages the IntersectionObserver API to detect when the user has scrolled to the bottom of a container and then triggers a callback to fetch more data.
| Prop Name | Type | Default | Description |
|---|---|---|---|
children |
ReactNode |
undefined |
The content to be displayed within the scrollable area. |
endMessage |
ReactNode |
undefined |
The message or component to display when there are no more items to load. |
loadingComponent |
ReactNode |
undefined |
A component to show while loading more items. |
next |
() => Promise<void> | void |
undefined |
A function to call when loading more items. This should fetch and append new data. |
hasMore |
boolean |
false |
A boolean flag indicating whether there are more items to load. |
wait |
number |
300 |
Throttling wait time in milliseconds for the next function to prevent multiple calls. |
observerMargin |
number |
10 |
Margin around the IntersectionObserver root in pixels to trigger the observer earlier or later. |
-
Children Rendering: The component renders its
childreninside the container where infinite scrolling is desired. -
Intersection Observer Setup: An
IntersectionObserveris created in theuseEffecthook. This observer is attached to a trigger element (divwithref={triggerRef}) at the bottom of the scrollable container. -
Observer Margin: The
rootMarginprop allows customization of how early or late theIntersectionObservershould trigger based on the scrolling. It can be set as a positive or negative number of pixels. -
Fetching More Items: The
nextfunction prop is a callback function that fetches more data. This function is throttled using thethrottleutility function to avoid rapid successive calls. -
Loading Indicator: If
loadingComponentis provided, it will be displayed while more items are being fetched. -
End Message: When there are no more items to load (
hasMoreisfalse), theendMessageis displayed.
import React, { useState } from 'react';
import InfiniteScroll from './InfiniteScroll';
const App = () => {
const [items, setItems] = useState([]);
const [hasMore, setHasMore] = useState(true);
const fetchMoreData = async () => {
// Fetch more data and append to the items array
// Example: fetching from an API
const newItems = await fetchMoreItemsFromAPI();
setItems(prevItems => [...prevItems, ...newItems]);
if (newItems.length === 0) {
setHasMore(false);
}
};
return (
<InfiniteScroll
next={fetchMoreData}
hasMore={hasMore}
loadingComponent={<div>Loading...</div>}
endMessage={<div>No more items to display.</div>}
observerMargin={100} // Trigger fetching 100px before the element is in view
>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
</InfiniteScroll>
);
};
export default App;- Throttling: The next function is throttled to improve performance by preventing rapid consecutive calls. The throttling interval can be adjusted using the wait prop.
- Customizing Trigger Margin: Use the observerMargin prop to adjust how soon the next batch of items should load as the user scrolls. This can help optimize user experience based on your layout and content length.
- Error Handling: Ensure to handle any errors inside the next function to prevent the application from crashing during the data fetching process.
- throttle: A utility function used to throttle calls to the next function, limiting how frequently it can be invoked.