Part 34: TanStack React Query: Server State, Caching & Invalidation

Part 34 Technology Updated September 12, 2026

Part 34: TanStack React Query: Server State, Caching & Invalidation

TanStack React Query is the definitive server-state synchronization library for React. It automates fetching, caching, synchronizing, and updating server state.


1. Setup

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

const queryClient = new QueryClient();

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

2. Fetching Data with useQuery

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

async function fetchArticles() {
  const res = await fetch('https://api.devifyblog.com/articles');
  if (!res.ok) throw new Error('Failed to fetch articles');
  return res.json();
}

export default function ArticleFeed() {
  const { data, isLoading, isError, error } = useQuery({
    queryKey: ['articles'],
    queryFn: fetchArticles,
    staleTime: 1000 * 60 * 5, // Cache is fresh for 5 minutes
  });

  if (isLoading) return <p>Loading articles...</p>;
  if (isError) return <p>Error: {error.message}</p>;

  return (
    <div>
      {data.map(article => (
        <h3 key={article.id}>{article.title}</h3>
      ))}
    </div>
  );
}

3. Mutating Data with useMutation and Cache Invalidation

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

export default function CreateArticleForm() {
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: async (newArticle) => {
      const res = await fetch('https://api.devifyblog.com/articles', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(newArticle),
      });
      return res.json();
    },
    onSuccess: () => {
      // Invalidate articles query: React Query automatically refetches the list in the background!
      queryClient.invalidateQueries({ queryKey: ['articles'] });
    },
  });

  const handleSubmit = (e) => {
    e.preventDefault();
    mutation.mutate({ title: 'New Article on React 19' });
  };

  return (
    <button onClick={handleSubmit} disabled={mutation.isPending}>
      {mutation.isPending ? 'Publishing...' : 'Publish Article'}
    </button>
  );
}

Key Takeaways

  • React Query manages server state caching, background re-validation, and deduplication.
  • Use useQuery for reads and useMutation for writes.
  • Invalidate query keys on mutation success to trigger instant background UI synchronization.

In Part 35, we enter Module 6 to explore Data Fetching Patterns with Fetch API and Axios!