Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 5x 2x 2x 5x 10x 10x 10x 10x 10x 10x 10x | import { useEffect, useRef } from 'react';
interface UseInfiniteScrollOptions {
hasNextPage: boolean;
isFetchingNextPage: boolean;
fetchNextPage: () => void;
rootMargin?: string;
}
/**
* Attaches an IntersectionObserver to a sentinel element.
* Calls fetchNextPage when the sentinel scrolls into the viewport.
*
* @returns ref — attach to the sentinel <div> at the bottom of the list
*/
export const useInfiniteScroll = ({
hasNextPage,
isFetchingNextPage,
fetchNextPage,
rootMargin = '300px',
}: UseInfiniteScrollOptions) => {
const sentinelRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const node = sentinelRef.current;
if (!node) return;
const observer = new IntersectionObserver(
(entries) => {
if (entries[0]?.isIntersecting && hasNextPage && !isFetchingNextPage) {
fetchNextPage();
}
},
{ rootMargin },
);
observer.observe(node);
return () => observer.disconnect();
}, [hasNextPage, isFetchingNextPage, fetchNextPage, rootMargin]);
return sentinelRef;
};
|