Skip to content

React Query

Server state management — caching, revalidation, retries and background updates for data you fetch.

Web & HTTPWebJavaScript

What it is

React Query is a powerful data-fetching library for React that simplifies fetching, caching, synchronizing, and updating server state in your React applications.

React Query provides hooks like `useQuery`, `useMutation`, and `useInfiniteQuery` to fetch and mutate data. It handles caching, background refetching, pagination, and stale data management automatically.

Best known for
Making the distinction between server state and client state obvious
Licence
MIT

When to use it

The question documentation cannot answer for you — because it cannot recommend something else.

Reach for it when

  • Any application that reads data from an API and needs it cached and kept fresh
  • You are currently writing loading and error state by hand in every component
  • You want optimistic updates, pagination or infinite scroll without building the machinery

Look elsewhere when

  • The app fetches once at startup and never again
  • You are on a framework with its own data layer that already handles caching

Installation

npm install @tanstack/react-query

Getting started

The smallest useful thing you can do with it, and what each part means.

Fetching data with useQuery
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

function App() {
  const { data, error, isLoading } = useQuery(['todos'], () => axios.get('/api/todos').then(res => res.data));

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error!</div>;

  return (
    <ul>
      {data.map(todo => <li key={todo.id}>{todo.title}</li>)}
    </ul>
  );
}
Fetches a list of todos from an API and automatically manages loading, error, and cached states.

Advanced usage

Where the library earns its place over a simpler alternative.

Mutating data with useMutation
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';

function AddTodo() {
  const queryClient = useQueryClient();
  const mutation = useMutation(newTodo => axios.post('/api/todos', newTodo), {
    onSuccess: () => queryClient.invalidateQueries(['todos'])
  });

  return <button onClick={() => mutation.mutate({ title: 'New Todo' })}>Add Todo</button>;
}
Adds a new todo item and invalidates the todos query to refresh cached data.
Paginated queries
const { data, isFetching, fetchNextPage } = useInfiniteQuery(['todos'], fetchTodos, {
  getNextPageParam: lastPage => lastPage.nextCursor
});
Demonstrates fetching data in pages and automatically handling pagination using `useInfiniteQuery`.
Query invalidation
const queryClient = useQueryClient();
queryClient.invalidateQueries(['todos']);
Manually invalidates cached queries to refetch fresh data from the server.
Prefetching data
queryClient.prefetchQuery(['todos'], fetchTodos);
Prefetches data in the background so it is ready when a component mounts.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Network error or failed request
Handle errors using the `error` property returned by `useQuery` or `useMutation` and provide fallback UI.
Stale data shown
Adjust `staleTime` to control when data is considered fresh and triggers background refetch.
Query not updating after mutation
Ensure to invalidate relevant queries using `queryClient.invalidateQueries` after successful mutations.

Best practices

  • Use `useQuery` for fetching data and `useMutation` for modifying data.
  • Leverage query keys for caching and invalidation granularity.
  • Use `staleTime` and `cacheTime` wisely to balance performance and freshness.
  • Prefetch data when possible for faster UI transitions.
  • Combine with `useQueryClient` for advanced cache manipulation and query invalidation.

Alternatives

Comparable options, and the reason you would pick one over the other.

Background

Why it exists, and what it was reacting to.

React Query was created by Tanner Linsley to solve common challenges in managing server state in React apps, such as caching, background updates, and synchronization. It allows developers to focus on building UI while React Query manages the complexity of data fetching and caching efficiently.