Blog>
Snippets

Implementing Infinite Scroll Pagination with UseInfiniteQuery

Illustrates how to use the useInfiniteQuery hook to implement an infinite scroll pagination mechanism, fetching additional data as the user scrolls.
import { useInfiniteQuery } from 'react-query';
import axios from 'axios';

const fetchPosts = async ({ pageParam = 1 }) => {
  const res = await axios.get(`https://jsonplaceholder.typicode.com/posts?_limit=10&_page=${pageParam}`);
  return res.data;
};
Define the fetchPosts function which fetches posts with Axios from a placeholder API, using pagination parameters.
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, status } = useInfiniteQuery(
  'posts',
  fetchPosts,
  {
    getNextPageParam: (lastPage, pages) => pages.length + 1,
  }
);
Use the useInfiniteQuery hook from React Query to fetch posts in an infinite loading pattern, using the fetchPosts function defined earlier. It automatically handles fetching the next page.
window.onscroll = async () => {
  if (window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
    if (hasNextPage && !isFetchingNextPage) {
      await fetchNextPage();
    }
  }
};
Attach an event listener to the window's scroll event to trigger the fetchNextPage function when the user scrolls to the bottom of the page, if there are more pages to load.
if (status === 'loading') return <div>Loading...</div>;
if (status === 'error') return <div>Error fetching data</div>;

return (
  <div>
    {data.pages.map((group, i) => (
      <React.Fragment key={i}>
        {group.map(post => (
          <p key={post.id}>{post.title}</p>
        ))}
      </React.Fragment>
    ))}
  </div>
);
Render the posts fetched by useInfiniteQuery, handling loading and error states. Displays posts in paragraphs separated by page groups.