05 July, 2022
Infinite scroll with React
How to create an infinite scroll component with React Hooks
First, we need a custom hook that will return true every time the user scrolls to the bottom of the component. For this, we use the intersection observer API
function useOnScreen(ref: React.RefObject<HTMLElement>) {
const [isIntersecting, setIntersecting] = React.useState(false);
const observer = new IntersectionObserver(([entry]) =>
setIntersecting(entry.isIntersecting)
);
useEffect(() => {
if (ref.current) {
observer.observe(ref.current);
}
return () => observer.disconnect();
}, []);
return isIntersecting;
}
export default useOnScreen;Now, we can utilize that custom hook on our Infinite Scroll component.
The component is a wrapper that adds a div element to the bottom.
We pass the div reference to our useOnScreen hook, so we will know every time this element is visible.
interface Props {
children: React.ReactNode;
callback: (nexPage: number) => void;
currentPage: number;
}
function InfiniteScroll({ children, callback, currentPage }: Props) {
const ref = React.useRef<HTMLDivElement>(null);
const isVisible = useOnScreen(ref);
useEffect(() => {
if (isVisible) callback(page + 1);
});
return (
<div>
{children}
<div ref={ref}></div>
</div>
);
}And we will use the component like so:
<InfiniteScroll
callback={(pageNumber) => getNextPage(pageNumber)}
page={currentPage}
>
<ul>
{allPages.map((item) => <li key={item.id}>{item.name}</li>)}
</ul>
</InfiniteScroll>