DoneDeal0
DoneDeal0

Reputation: 6257

How to invalidate cache with React query v3?

I have read react-query documentation regarding query invalidation. However, it doesn't seem to work for me. Here is the code:

import React from "react";
import ax from "axios";
import { useQueryClient, useQuery } from "react-query";

export default function App() {
  const queryClient = useQueryClient();
  const [poke, setPoke] = React.useState("pikachu");
  
  const getPokemon = async (id) => {
    try {
      const pokemon = await ax.get("https://pokeapi.co/api/v2/pokemon/" + id);
      return pokemon;
    } catch (err) {
      throw new Error();
    }
  };

  const { data, isLoading, isError } = useQuery(
    ["get-pokemon", poke],
    () => getPokemon(poke),
    { cacheTime: 100000000 }
  );

  const getGengar = () => {
    ax.get("https://pokeapi.co/api/v2/pokemon/gengar").then((res) => {
      queryClient.invalidateQueries("get-pokemon");
    });
  };

  return (
    <>
      {isLoading && "loading"}
      {isError && "error"}
      {data && data.data.id}
      <button onClick={() => setPoke("pikachu")}>search pikachu</button>
      <button onClick={() => setPoke("ditto")}>search ditto</button>
      <button onClick={() => getGengar()}>search gengar</button>
    </>
  );
}

So the function getGengar() should invalidate the query "get-pokemon". I should see a loading state when pressing the "get pikachu" button again. But it behaves like the cache is still valid. How to fix this?

Upvotes: 7

Views: 12055

Answers (1)

NearHuscarl
NearHuscarl

Reputation: 81270

From react-query docs - query invalidation.

When a query is invalidated with invalidateQueries, two things happen:

  • It is marked as stale.
  • If the query is currently being rendered via useQuery or related hooks, it will also be refetched in the background.

Also in important defaults section:

  • Stale queries are refetched automatically in the background when there are new activities (query instance mounted, window refocused, network reconnected...)

To recap, when you call invalidateQueries(), it makes all matching queries stale and stale queries when interacted are fetched again in the background. If you want to show loading state, there are 2 states you can refer to depending on the scenario:

  • isLoading: returns true when fetching for the first time or after query cache is garbage collected (no cache).
  • isFetching: returns true when refetching in the background. Happens when there is stale cache to display as a placeholder.
const {
  isFetching, // returns true when in the fetching process
  isLoading, // returns true when in the fetching process AND no cache
  ...props,
} = useQuery(
  ["id", idQuery],
  fetchSomething
);

Upvotes: 8

Related Questions