Query Invalidation in React Query

Published on 12 Oct, 2021

React Query by default has its own techniques to sync server state with the client. It fetches fresh data on 4 instances.

  1. New instances of the query mount
  2. Window focus
  3. Network reconnection
  4. Query that is configured with refetch interval

Other than these 4 scenarios, what if we need to forcefully make React Query to refetch the content from the server? We can make use of invalidateQueries() method.

Here, we have a RandomCoffee component that shows a random coffee name from random-data-api.com.

import { useQuery, QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
import axios from "axios";

const queryClient = new QueryClient();

function RandomCoffee() {
  const randomCoffee = useQuery("coffee", async () => {
    const { data } = await axios.get(
      "https://random-data-api.com/api/coffee/random_coffee"
    );
    return data;
  });
  return (
    <>
      {randomCoffee.isLoading ? (
        <h1>Loading...</h1>
      ) : (
        <div>
          <h1>{randomCoffee.data.variety}</h1>
          <button>Get Fresh Coffee</button>
        </div>
      )}
    </>
  );
}

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <RandomCoffee />
      <ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
    </QueryClientProvider>
  );
}

export default App;

The code now contains a button that does nothing. We need to fetch a new coffee name when we click on the button. For that we can invoke queryClient.invalidateQueries("coffee") on button click.

<button onClick={() => queryClient.invalidateQueries("coffee")}>
  Get Fresh Coffee
</button>

Passing the query key to invalidateQueries will invalidate only that specific query. We can invalidate all queries by invoking the method without any arguments.