Enable Dark Mode!
how-to-fetch-paginated-data-with-tanstack-query-in-react.jpg
By: Alan Joy

How to Fetch Paginated Data with TanStack Query in React

Technical React

When building a modern React application, we often need to work with large datasets. Instead of loading these large datasets all at once, applications usually fetch the data page by page. This approach is called pagination. Use of pagination can improve the application performance, reduce the load time, and can create a smoother user experience.

In this blog, we will learn how to fetch and handle the paginated data in a React application using the Tanstack Query package. We will build a simple application step by step and learn how pagination works in a real application.

What Is TanStack Query?

TanStack Query, formerly known as React Query, is a powerful data-fetching library for React. TanStack Query can help you easily fetch server data, cache the return response, and automatically handle the loading, error handling, and refetching logics. It can also manage the pagination and infinite scrolling efficiently. Instead of manually handling the api states with useEffect and useState, TanStack Query simplifies the entire process.

Why Use Pagination?

Imagine that an API is returning 10,000 users. Fetching all the data at once would result in slowing down your application and creating performance issues. It can also increase network usage. Pagination can solve these problems by loading only the data needed for the current page. This keeps the application fast and efficient.

Create a React App

First, create a React app using Vite and install the TanStack Query package.

npm create vite@latest
npm install
npm install @tanstack/react-query

Set Up QueryClient

Now we need to setup query client. Open your main.jsx or main.tsx file. The QueryClientProvider gives the app access to the Tanstack query features.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import {
  QueryClient,
  QueryClientProvider,
} from "@tanstack/react-query";
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById("root")).render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>
);

Create the Fetch Function

Now we need to set up an API fetching function. Here I am using a dummy json api, for your app, update it with the actual server api. Update App.jsx file with this function.

const fetchProducts = async (page) => {
  const limit = 10;
  const skip = (page - 1) * limit;
  const response = await fetch(
    `https://dummyjson.com/products?limit=${limit}&skip=${skip}`
  );
  if (!response.ok) {
    throw new Error("Failed to fetch products");
  }
  return response.json();
};

Fetch Paginated Data with useQuery

Now we can fetch the data using useQuery.

import { useState } from "react";
import { useQuery, keepPreviousData } from "@tanstack/react-query";
const fetchProducts = async (page) => {
  const limit = 10;
  const skip = (page - 1) * limit;
  const response = await fetch(
    `https://dummyjson.com/products?limit=${limit}&skip=${skip}`
  );
  if (!response.ok) {
    throw new Error("Failed to fetch products");
  }
  return response.json();
};
export default function App() {
  const [page, setPage] = useState(1);
  const { data, isPending, isError, error, isFetching } =
    useQuery({
      queryKey: ["products", page],
      queryFn: () => fetchProducts(page),
      placeholderData: keepPreviousData,
    });
  if (isPending) {
    return <h2>Loading...</h2>;
  }
  if (isError) {
    return <h2>{error.message}</h2>;
  }
  return (
    <div style={{ padding: "20px" }}>
      <h1>Products</h1>
      {data.products.map((product) => (
        <div
          key={product.id}
          style={{
            border: "1px solid #ddd",
            padding: "10px",
            marginBottom: "10px",
          }}
        >
          <h3>{product.title}</h3>
          <p>${product.price}</p>
        </div>
      ))}
      <div style={{ display: "flex", gap: "10px" }}>
        <button
          onClick={() =>
            setPage((prev) => Math.max(prev - 1, 1))
          }
        >
          Previous
        </button>
        <span>Page {page}</span>
        <button
          onClick={() => setPage((prev) => prev + 1)}
        >
          Next
        </button>
      </div>
      {isFetching && <p>Fetching new data...</p>}
    </div>
  );
}

queryKey

queryKey: ["products", page]

The query key should change whenever the page changes. This tells the tanstack query to fetch different data for each page.

queryFn

queryFn: () => fetchProducts(page)

This function will run whenever the query key changes. When the user moves from page 1 to page 2, the query function runs with the updated page number.

keepPreviousData

placeholderData: keepPreviousData

With this feature, the previous page data stays visible, and new data loads smoothly in the background.

Pagination is an important feature in a modern React application. It is a necessary part, especially when working with APIs and large datasets. Using the Tanstack query makes this process much simpler by handling the caching, loading, and error states, background updates, and pagination logics. With a few lines of code, we can create a fast and smooth paginated ui without managing complex states manually.

To read more about Overview of React Query for Beginners, refer to our blog Overview of React Query for Beginners.


Frequently Asked Questions

What is the difference between isPending and isFetching?

isPending runs during the first fetch, while isFetching runs whenever new data is being fetched in the background.

Why should I use keepPreviousData?

It prevents UI flickering and keeps old data visible while the next page loads.

Should I use pagination or infinite scrolling?

Use pagination for tables and dashboards. Use infinite scrolling for feeds and continuously loading content.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message