React Query by default has its own techniques to sync server state with the client. It fetches fresh data on 4 instances.
- New instances of the query mount
- Window focus
- Network reconnection
- 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.