tezvyn:

TanStack Query: Managing Server State, Not Client State

AI-drafted, machine-checkedSource: tanstack.comintermediate
TanStack Query: Managing Server State, Not Client State

TanStack Query manages asynchronous server state, not client-side UI state. It treats server data as a cached resource. Use it to fetch, cache, and update remote data automatically. The footgun is using it for synchronous client state like form inputs.

WHY IT EXISTS: Client-side state (like a form's value) is synchronous and owned by the user. Server state is asynchronous, remote, and can be changed by others. Managing server state with client state tools requires a lot of boilerplate for caching, refetching, and invalidation. TanStack Query was built specifically for this problem.

THE MENTAL MODEL: Think of TanStack Query as a smart, declarative cache for your server data that lives inside your client application. Instead of telling your app HOW to fetch data (e.g., in a useEffect), you tell it WHAT data you need, and Query handles the when and how of fetching, caching, and updating it. It separates server state management from client state management.

HOW IT WORKS: You provide a unique queryKey (an array that acts as a dependency) and a queryFn (an async function that returns data). TanStack Query uses the key to cache the data. It automatically handles fetching, background refetching on window focus, retries on error, and provides status flags like isLoading, isError, and isSuccess. Mutations (useMutation) are used to create, update, or delete data, with tools to invalidate cached queries and trigger refetches.

WHEN TO USE IT: Use it for any data that lives on a server. This includes fetching user profiles, lists of items, search results, and configuration data. It's especially powerful for complex UI patterns like paginated tables, infinite scroll lists, and performing optimistic updates where the UI updates before the server confirms the change.

WHEN NOT TO USE IT: Do not use it for state that is purely local to the client and synchronous. Examples include the state of a controlled form input, whether a modal is open, or the current theme (dark/light mode). For these, use standard state management (useState, useReducer) or a dedicated client state library if needed.

ONE CANONICAL EXAMPLE: A common use case is fetching a list of todos. With useQuery, you'd define a query key like ['todos'] and a function to fetch from an API. Query automatically provides a 'data' object, an 'isLoading' boolean for showing a spinner, and an 'isError' flag. If the user navigates away and comes back, Query can automatically refetch the data to ensure it's not stale.

Read the original → tanstack.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.