Data Fetching in React with TanStack Query

A
Author
03 Jun, 2026 1 min read 823 views

Fetching in useEffect means handling loading, errors, caching, refetching and race conditions yourself. TanStack Query (formerly React Query) handles all of that for client-side data.

Setup

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Projects />
    </QueryClientProvider>
  );
}

Reading data with useQuery

import { useQuery } from '@tanstack/react-query';

function Projects() {
  const { data, isPending, error } = useQuery({
    queryKey: ['projects'],
    queryFn: () => fetch('/api/projects').then((r) => r.json()),
    staleTime: 60_000, // treat as fresh for a minute
  });

  if (isPending) return <p>Loading...</p>;
  if (error) return <p>Something went wrong.</p>;
  return data.map((p) => <ProjectCard key={p.id} project={p} />);
}

Query keys

The key identifies the data in the cache. Include every variable the request depends on:

useQuery({ queryKey: ['projects', { status, page }], queryFn: () => fetchProjects({ status, page }) });

Changing data with useMutation

import { useMutation, useQueryClient } from '@tanstack/react-query';

function NewProject() {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: (name) => fetch('/api/projects', { method: 'POST', body: JSON.stringify({ name }) }),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['projects'] }), // refetch lists
  });

  return (
    <button disabled={mutation.isPending} onClick={() => mutation.mutate('Website redesign')}>
      Create project
    </button>
  );
}

What you get for free

  • Shared cache: two components using the same key make one request.
  • Background refetch when the window regains focus or the network reconnects.
  • Retries with backoff, pagination and infinite queries.
  • Devtools to inspect the cache.

If you use a framework with Server Components, fetch on the server where you can and use TanStack Query for interactive, client-driven data.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.