react-use-infinite-loader
v1.0.0
Published
Infinitely load new content in React using a simple React hook
Downloads
208
Readme
react-use-infinite-loader :infinity: :page_with_curl: :hourglass_flowing_sand:
Super lightweight infinite loading hook for React apps
react-use-infinite-loader
uses the IntersectionObserver
to provide a performant solution to infinite scrolling that doesn't involve scroll event listeners.
:warning: Some older browsers may not support the IntersectionObserver
API, however you can easily polyfill the functionality with this.
As the name suggests react-use-infinite-loader
uses React Hooks, so you need to be using React function components to use this library.
Usage
See
example/
for a full example (recommended), run it locally withyarn start
. Also view it in the browser
Install with
yarn add react-use-infinite-loader
Add to your app
import useInfiniteLoader from 'react-use-infinite-loader';
Implement the hook. Ensure that the initial content page size flows off the page so that the next page isn't instantly fetched
const [canLoadMore, setCanLoadMore] = React.useState(true);
const [data, setData] = React.useState([]);
const loadMore = React.useCallback((page) => {
loadFromAPI(page).then(response => {
setCanLoadMore(response.canLoadMore);
setData(currentData => [...currentData, ...response.data]);
});
});
const { loaderRef } = useInfiniteLoader({ loadMore, canLoadMore });
Give the loaderRef
that's returned from the hook to a div
that sits directly below your rendered content list. Give it a classname that you'll use in the next step.
return (
<>
<h1>My App</h1>
{items.map(item => <div>{item}</div>)}
<div ref={loaderRef} className="loaderRef" />
</>
);
Add the following CSS to your apps to allow the observer to see the div and know to load more data. Note that if you always have a DOM node with at least 1px height and width below the loaderRef
div then you don't need to add this CSS. A common example where the CSS isn't required would be {canLoadMore && <div>Loading page {page + 1}</div>}
.
/* You can change the name here and in your JSX if you want to */
.loaderRef {
width: 1px;
height: 1px;
position: absolute;
}
API Reference
useInfiniteLoader
arguments object
| Property | Default value | Description |
| - | - | - |
| loadMore | required | Invoked when the user scrolls into the observable viewport + its rootMargin; read about rootMargin and thresholds here. |
| canLoadMore | false
| Tells useInfiniteLoader whether to run loadMore
when the observer is triggered, this is usually set dynamically. |
| rootMargin | "100px 0px 0px 0px"
| Read about rootMargin
here. |
| threshold | 0
| Read about threshold
here. |
| initialise | true
| Used for if your data fetching library fetches page 0 and renders it when the component loads, to use this just have a state flag that you set to false once the initial load from your data fetching lib has happened. |
| startFromPage | 0
| Used if you already load page 0 on mount, you can tell useInfiniteLoader what page to begin loading more from. |
| debug | false
| Prints some helpful messages about what useInfiniteLoader is doing. |
useInfiniteLoader
result object
| Property | Description |
| - | - |
| loaderRef
| A React ref that you must pass to an element via ref={loaderRef}
, this element must sit directly below your list of items that you're loading |
| page
| The current page that useInfiniteLoader
has loaded |
| resetPage
| A function that resets the current page to startFromPage
(default 0
). This is useful if you change the context of the page but the component instance is the same |