3 min read React Query · Part 11 of 12

React Query - Paginated List

Hey Folks, Today it's time to learn how you can paginate a list with ReactQuery. It's common to...

#react #reactquery #reacthooks
Luca Del Puppo Luca Del Puppo
Article Series · Part 11 of 12 React Query
View full series (12)
  1. #10 Previous
    Abort Request
  2. #11 Reading now
    Paginated List
  3. #12 Up next
    Infinite Queries
Browse all 12 parts in this series
  1. #1 useQuery
  2. #2 useMutation
  3. #3 useIsFetching & useIsMutation
  4. #4 DevTools
  5. #5 Authentication Flow
  6. #6 Filter Your Data
  7. #7 Enable Query
  8. #8 Keys & Prefetching
  9. #9 Improve user experience with optimistic update
  10. #10 Abort Request
  11. #11 Paginated List Current
  12. #12 Infinite Queries

Hey Folks,

Today it’s time to learn how you can paginate a list with ReactQuery.

It’s common to create a pagination of a list to improve the user interface of your platform if you are building a list in your application, but also to limitate the work in your API.

Using ReactQuery, building a paginate list is a piece of cake.

You have to follow 3 steps:

  1. Create a state to save the value of the current page

  2. Create a state to save the limit of the pages (the number of elements on every page)

  3. Fetch the data every time the user changes one of the previous states.

But let’s see an example that is easier to understand

const fetchTodos = async (
  page: number,
  limit: number,
  signal: AbortSignal | undefined
): Promise<{
  totals: number;
  todos: Todo[];
}> => {
  const response = await fetch(`api/tasks?_page=${page}&_limit=${limit}`, {
    signal,
  });
  if (!response.ok) {
    throw new ResponseError('Failed to fetch todos', response);
  }
  const todos: Todo[] = await response.json();
  const totals = Number.parseInt(
    response.headers.get('x-total-count') || '0',
    10
  );

  return {
    totals,
    todos,
  };
};

interface UseTodos {
  todos: Todo[];
  isLoading: boolean;
  isFetching: boolean;
  error?: string;
  pages: number;
  page: number;
  setPage: Dispatch<SetStateAction<number>>;
}

export const useTodos = (): UseTodos => {
  const [page, setPage] = useState<number>(1);
  const [limit] = useState<number>(5);

  const {
    data: { todos, totals } = {
      todos: [],
      totals: 0,
    },
    isLoading,
    isFetching,
    error,
  } = useQuery(
    [QUERY_KEY.todos, page, limit],
    ({ signal }) => fetchTodos(page, limit, signal),
    {
      refetchOnWindowFocus: false,
      retry: 2,
    }
  );

  return {
    todos,
    isLoading,
    isFetching,
    error: mapError(error),
    pages: Math.ceil(totals / limit),
    page,
    setPage,
  };
};

As you can notice, the process to build a pagination with ReactQuery is very simple.
The fetch request has to contain the page and the limit (you can handle a pagination also with limit and offset if you want) and in your useQuery you have to handle some simple stuff. First, the key of your query must include the page and limit too, second you must pass page and limit to your fetch request.

As you can see, building a paginated list with ReactQuery is really a piece of cake, but if want to dive into it don’t miss my youtube video about it

🎬 Watch / View Embedded Resource: https://www.youtube.com/watch?v=Ma7-hdNMdWs

I think thats all from this article; I hope you enjoyed this content!

See you soon folks
Bye Bye 👋

p.s. you can find the code of the video in the GitHub repository

Photo by Rahul Mishra on Unsplash

🎬 Watch / View Embedded Resource: https://dev.to/puppo

Luca Del Puppo

Written by Luca Del Puppo

Run, Code & Learn

AI Native Engineer at Nearform based in Povegliano (TV), Italy. Google Developer Expert in Web Technologies, GitKraken Ambassador, and Codemotion Ambassador.