How to Debug React Query in React
Debugging React Query (TanStack Query) is essential for monitoring network requests, cache states, and query lifecycles in your React applications. This article provides a straightforward guide on how to debug React Query effectively using the official Devtools, inspecting cache states programmatically, and leveraging global callbacks for custom logging.
1. Use the Official React Query Devtools
The easiest and most powerful way to debug React Query is by using the official Devtools package. It provides a visual representation of all queries, their states (loading, fetching, stale, inactive), and the cached data.
Installation
Install the Devtools package via npm or yarn:
npm install @tanstack/react-query-devtools
# or
yarn add @tanstack/react-query-devtoolsIntegration
Import and render the <ReactQueryDevtools />
component inside your application, typically right next to your
QueryClientProvider.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourAppComponent />
{/* Devtools will only be included in development builds */}
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}Once added, a floating React Query logo will appear in the corner of your screen in development mode. Clicking it opens the dashboard where you can manually trigger refetches, reset queries, or inspect the exact JSON structure of your cached data.
2. Leverage Global Cache Callbacks
If you need to debug query behaviors programmatically or log errors
to an external service (like Sentry), you can configure global callbacks
on the QueryCache and MutationCache when
initializing your QueryClient.
import { QueryClient, QueryCache, MutationCache } from '@tanstack/react-query';
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error, query) => {
console.error(`Query Error [${query.queryKey}]:`, error);
},
}),
mutationCache: new MutationCache({
onError: (error, variables, context, mutation) => {
console.error(`Mutation Error [${mutation.options.mutationKey}]:`, error);
},
}),
});This ensures that whenever any query or mutation fails, the error is immediately logged to your console with its associated query key.
3. Inspect the Cache Programmatically
You can programmatically inspect the entire state of your React Query
cache at any time using the QueryClient instance. This is
useful for custom console logging during specific user actions.
// Get all queries currently in the cache
const queries = queryClient.getQueryCache().getAll();
// Get data for a specific query key
const cachedData = queryClient.getQueryData(['userData']);
console.log('Current cached user data:', cachedData);4. Monitor Network Activity
Because React Query manages an asynchronous state layer on top of your HTTP requests, you should always cross-reference React Query’s state with your browser’s Network tab.
- If React Query shows a query is “fetching” but no network request appears, the query is likely resolving from a local cache or a custom offline handler.
- If a network request finishes but React Query doesn’t update, verify that your query function is properly returning the resolved promise data.