Infinite Scrolling with useInfiniteQuery
Implement infinite scrolling for posts in a blog application using the useInfiniteQuery hook, including loading more posts when the user scrolls to the bottom of the page.
import { useInfiniteQuery } from 'react-query';
import React, { useEffect } from 'react';
Import the useInfiniteQuery hook from react-query and useEffect from React.
const fetchPosts = async ({ pageParam = 1 }) => {
const res = await fetch(`/api/posts?page=${pageParam}`);
return res.json();
};
Define the fetchPosts function to fetch posts from an API, pageParam sets the current page.
const InfinitePosts = () => {
const { data, hasNextPage, fetchNextPage, isFetchingNextPage } = useInfiniteQuery('posts', fetchPosts, {
getNextPageParam: (lastPage, pages) => lastPage.nextPage ?? undefined
});
In the InfinitePosts component, use the useInfiniteQuery hook to fetch posts and manage pagination.
useEffect(() => {
const handleScroll = () => {
if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight || isFetchingNextPage) return;
fetchNextPage();
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [fetchNextPage, isFetchingNextPage]);
Set up an effect to listen for the scroll event and call fetchNextPage when reaching the bottom of the page.
return (
<div>
{data.pages.map((group, i) => (
<React.Fragment key={i}>
{group.results.map(post => (
<p key={post.id}>{post.title}</p>
))}
</React.Fragment>
))}
<div>{isFetchingNextPage ? 'Loading more...' : hasNextPage ? 'Scroll for more posts' : 'No more posts'}</div>
</div>
);
};
Render the posts and a loading message or 'no more posts' message based on the fetch state.
export default InfinitePosts;
Export the InfinitePosts component for use in the application.