Infinite scroll component for react.
npm install better-react-infinite-scrollA react infinite scroll component made with modern Intersection Observer API, meaning it will be much more performant. Small and easy to customize, written with typescript as a functional component.
I made this component because I found other solutions such as react-finite-scroll-component and react-infinite-scroller was large, written as class component, and unnecessarily hard to customize.
``ts
import React from "react";
interface InfiniteScrollProps extends React.HTMLAttributes
fetchNextPage: () => void;
hasNextPage: boolean;
loadingMessage: React.ReactNode;
endingMessage: React.ReactNode;
}
// eslint-disable-next-line react/display-name
export const InfiniteScroller = React.forwardRef<
HTMLDivElement,
InfiniteScrollProps
>(
(
{
fetchNextPage,
hasNextPage,
endingMessage,
loadingMessage,
children,
...props
},
ref
) => {
const observerTarget = React.useRef(null);
React.useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
if (entries[0]?.isIntersecting && hasNextPage) fetchNextPage();
},
{ threshold: 1 }
);
if (observerTarget.current) {
observer.observe(observerTarget.current);
}
return () => observer.disconnect();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
How to use: normal scroll
`ts
import { InfiniteScroller } from "better-react-infinite-scroll";return (
fetchNextPage={fetchNextPage}
hasNextPage={hasNextPage}
loadingMessage={
Loading...
}
endingMessage={The beginning of time...
}
// className="overflow-auto" <= scroll target, may or may not need this
>
{elements.map((el) => (
{el}
))}
);
`How to use: inverse scroll
For inverse scroll, use flex-direction: column-reverse. Scoller height must be defined. Here we use tailwind flex-1 (flex: 1 1 0%) but height: 300px would also work for example.
`ts
import { InfiniteScroller } from "better-react-infinite-scroll";return (
fetchNextPage={fetchNextPage}
hasNextPage={hasNextPage}
loadingMessage={Loading...
}
endingMessage={The beginning of time...
}
className="flex flex-1 flex-col-reverse overflow-auto"
>
{elements.map((el) => (
{el}
))}
);
`Need a grid to infinite scroll? Try this modification.
`ts
...
return (
{children}
{hasNextPage ? loadingMessage : endingMessage}
);
``