Categories
React

Making HTTP Requests with React Query — Paginated and Infinite Scroll Queries

Spread the love

The React Query library lets us make HTTP requests easily in our React apps.

In this article, we’ll look at how to make HTTP requests with React Query.

Paginated Queries

We can make paginated queries as we do with any other queries with the useQuery hook.

For instance, we can write:

index.js

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider } from "react-query";
import App from "./App";

const queryClient = new QueryClient();

const rootElement = document.getElementById("root");
ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <StrictMode>
      <App />
    </StrictMode>
  </QueryClientProvider>,
  rootElement
);

App.js

import axios from "axios";
import React from "react";
import { useQuery } from "react-query";
export default function App() {
  const [page, setPage] = React.useState(1);
  const { data: { data: { data, totalPages } } = { data: [] } } = useQuery(
    ["todo", page],
    ({ queryKey: [, page] }) => {
      return axios(
        `https://api.instantwebtools.net/v1/passenger?page=${page}&size=10`
      );
    }
  );

  return (
    <div>
      <button onClick={(p) => setPage(Math.max(1, page - 1))}>prev</button>
      <button onClick={(p) => setPage(Math.min(totalPages, page + 1))}>
        next
      </button>
      <div>
        {Array.isArray(data) &&
          data.map((d, i) => <p key={`${i}-${d.name}`}>{d.name}</p>)}
      </div>
    </div>
  );
}

We just create the page state and pass it into the request to make a paginated query.

We’ll see that there’s a lot of flashing since every query is going to make as a new query.

To make the queries without the extra flashing, we set the keepPreviousData option to true :

App.js

import axios from "axios";
import React from "react";
import { useQuery } from "react-query";
export default function App() {
  const [page, setPage] = React.useState(1);
  const { data: { data: { data, totalPages } } = { data: [] } } = useQuery(
    ["todo", page],
    ({ queryKey: [, page] }) => {
      return axios(
        `https://api.instantwebtools.net/v1/passenger?page=${page}&size=10`
      );
    },
    {
      keepPreviousData: true
    }
  );

  return (
    <div>
      <button onClick={(p) => setPage(Math.max(1, page - 1))}>prev</button>
      <button onClick={(p) => setPage(Math.min(totalPages, page + 1))}>
        next
      </button>
      <div>
        {Array.isArray(data) &&
          data.map((d, i) => <p key={`${i}-${d.name}`}>{d.name}</p>)}
      </div>
    </div>
  );
}

Infinite Queries

We can also use React Query to make requests for infinite scrolling.

To do this, we use the useInfiniteQuery hook.

This lets us display all the items that have been fetched so far.

For instance, we can write:

import axios from "axios";
import React from "react";
import { useInfiniteQuery } from "react-query";
export default function App() {
  const [page, setPage] = React.useState(1);
  const { data, fetchNextPage } = useInfiniteQuery(
    "names",
    ({ pageParam = 1 }) => {
      return axios(
        `https://api.instantwebtools.net/v1/passenger?page=${pageParam}&size=10`
      );
    },
    {
      getNextPageParam: (lastPage) => {
        const { totalPages } = lastPage.data;
        return page < totalPages ? page + 1 : totalPages;
      }
    }
  );

  return (
    <div>
      <div>
        {data &&
          Array.isArray(data.pages) &&
          data?.pages.map((group, i) => {
            return group?.data?.data.map((d, i) => (
              <p key={`${i}-${d.name}`}>{d.name}</p>
            ));
          })}
      </div>
      <button
        onClick={() => {
          setPage(page + 1);
          fetchNextPage();
        }}
      >
        load more
      </button>
    </div>
  );
}

We call the useInfiniteQuery hook with the identifier for the request as the first argument.

The 2nd argument is the query function.

It takes an object with the pageParam property as the parameter.

pageParam is the return value of the getNextPageParam function.

getNextPageParam returns the next value of pageParam .

Then in the JSX, we return the data.pages array with the array of pages.

And we call map to render the data with the data from the page.

The load more button calls fetchNextPage to fetch the next page.

Conclusion

We can create paginated and requests for infinite scrolling with React Query.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *