Skip to content
John (Caner) Kuru

3 min read

React Query: isLoading vs isFetching

In depth look at React Query's isFetching and isLoading API

ReactQuery, also known as TanStack Query, is a library that provides a simple, yet powerful way to fetch, cache, and manage data in your React applications. It is designed to work seamlessly with the React ecosystem.

This library's got a ton of cool hooks for working with APIs. I've been mostly messing around with useQuery, useMutation, and useInfiniteQuery. Each one returns an object packed with super handy properties. I won't get into every single one in this blog post, but do yourself a favor and check them out here.

Heads up! This documentation is tailored for TanStack Query v4. The developers have recently released TanStack Query v5. Explore the new version here.

API Properties

The properties that seem to cause the most confusion are isLoading, isFetching, and isRefetching. Let me explain what those are:

isLoading: This state is set to true exclusively during the initial data fetching.

isFetching: This state is true every time an API call is made, regardless if we did it manually or not.

isRefetching: This state is only true when we're deliberately refetching with the refetch() function.

Here is an example code that you can test out:

import {
  useQuery,
  QueryClient,
  QueryClientProvider,
} from "@tanstack/react-query";

const queryClient = new QueryClient();

export default function Home() {
  return (
    <QueryClientProvider client={queryClient}>
      <RandomName />
    </QueryClientProvider>
  );
}

const RandomName = () => {
  const { data, isLoading, isFetching, isRefetching, refetch } = useQuery({
    queryKey: ["randomName"],
    queryFn: async () => {
      const response = await fetch("https://randomuser.me/api/");
      const data = await response.json();
      return data;
    },
    retry: 1,
  });

  console.log("isLoading", isLoading);
  console.log("isFetching", isFetching);
  console.log("isRefetching", isRefetching);

  return (
    <div>
      <button
        onClick={() => {
          refetch();
        }}
      >
        Fetch Again!
      </button>
    </div>
  );
};

Here's a breakdown of the properties used:

queryKey: A unique key for the query. Query keys have to live in an array after version 4. This is used to identify and manage the cache of this query. (Example: [“user”], [“user”, user.id]) queryFn: This function returns the promise which gets the data. In this case, the data is fetched from the https://randomuser.me/api/ API endpoint. retry: Number of attempt retries in case the query fails. The destructured properties you 'get from useQuery are as follows:

data: This contains the actual data returned by the query. refetch: This is a function that you can call to manually trigger a refetch of the query. isLoading, isFetching, isRefetching explain above!

Preview: Initial fetch

Preview: Manual fetching

Basically, isLoading returns true when you're fetching data for the first time. On the other hand, isFetching will be true anytime there's an ongoing data fetching process, not just for the first time. Lastly, isRefetching only becomes true when you manually ask for the data to be fetched again by using the refetch() function.

Tanstack Query equips us with extraordinarily potent hooks that grant us limitless possibilities. I wholeheartedly believe that this library is ahead of its time, and I intend to incorporate it into all my future projects. I would genuinely appreciate hearing your thoughts on my explanation, and do let me know if any segment appears unclear. Your feedback is valuable to me!