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-devtools

Integration

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.