45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
|
|
export function useInfiniteItemsObserver({
|
|
bottomObserverRef,
|
|
fetchNextPage,
|
|
hasNextPage,
|
|
isFetchingNextPage,
|
|
}: {
|
|
bottomObserverRef: React.RefObject<HTMLLIElement>;
|
|
fetchNextPage: () => void;
|
|
hasNextPage: boolean;
|
|
isFetchingNextPage: boolean;
|
|
}) {
|
|
const bottomObserver = React.useCallback(
|
|
(entries: IntersectionObserverEntry[]) => {
|
|
const [entry] = entries;
|
|
if (entry?.isIntersecting && hasNextPage && !isFetchingNextPage) {
|
|
fetchNextPage();
|
|
}
|
|
},
|
|
[fetchNextPage, hasNextPage, isFetchingNextPage],
|
|
);
|
|
|
|
// Setup bottom observer
|
|
React.useEffect(() => {
|
|
const bottomObserverElement = bottomObserverRef.current;
|
|
|
|
// Bottom observer
|
|
const observerBottom = new IntersectionObserver(bottomObserver, {
|
|
root: null,
|
|
rootMargin: "100px",
|
|
threshold: 0.1,
|
|
});
|
|
|
|
if (bottomObserverElement) observerBottom.observe(bottomObserverElement);
|
|
|
|
return () => {
|
|
if (bottomObserverElement)
|
|
observerBottom.unobserve(bottomObserverElement);
|
|
};
|
|
}, [bottomObserver, bottomObserverRef]);
|
|
}
|