← Back

React.js + Next.js · Module 4. React Query and Formik · Lesson 1 · Point 1

Introduction to Server Data and React Query

React + TypeScript · GoIT Dev Notes

This lesson introduces server data and the problems that appear when asynchronous requests, status flags, caching, retries, and pagination are managed manually.

You will learn the purpose of TanStack Query, formerly commonly called React Query, and understand its core concepts before building a complete project in the next lesson.


REACT QUERY · 01

1. What Is Server Data?

Server data is information owned by a remote system and requested by the client application. Examples include products, users, tasks, comments, weather reports, and search results.

Unlike local UI state, server data has characteristics that the browser does not fully control:

  • It arrives asynchronously.
  • It may become outdated while the application is open.
  • Other users or systems may change it.
  • Requests can fail or take a long time.
  • Several components may need the same response.
Client stateServer data
Modal visibilityProduct list from an API
Selected tabUser account returned by a server
Input textSearch results
Temporary counterPaginated orders

React can store both kinds of information, but server data needs additional request and synchronization behavior.

REACT QUERY · 02

2. Pending, Error, and Success

In TanStack Query v5, a query has one primary status at a time:

StatusConvenience flagMeaning
pendingisPendingNo successful data is available yet.
errorisErrorThe query ended with an error.
successisSuccessData is available.

Beginner lessons often describe these as loading, error, and data. The current API uses pending, error, and success for the main status model.

Visual Result

Query states

Pending

No data yet.

isPending: true

Error

The request failed.

isError: true

Success

Data is ready.

isSuccess: true
The primary status describes whether usable data exists or the query failed.

REACT QUERY · 03

3. Problems with Manual State Management

A manual request often starts with several pieces of state and an Effect:

const [data, setData] = useState<Product[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);

useEffect(function () {
  // Start request, update three states, handle cleanup...
}, []);

As the application grows, more responsibilities appear:

  • Preventing outdated responses from replacing newer ones.
  • Sharing responses between components.
  • Avoiding duplicate requests.
  • Deciding when cached data is stale.
  • Refetching after focus or reconnection.
  • Retrying temporary failures.
  • Coordinating pagination and previous data.

Manual fetching is not inherently wrong, but repeated server-state logic becomes difficult to maintain consistently.

REACT QUERY · 04

4. What Is React Query?

TanStack Query is a library for fetching, caching, synchronizing, and updating asynchronous server data. The React package is @tanstack/react-query.

A query needs two central pieces:

  • A unique query key that identifies the data.
  • A query function that returns a Promise.
const query = useQuery({
  queryKey: ["products"],
  queryFn: fetchProducts,
});

The key connects the request to its cached result. TanStack Query then exposes data, errors, status flags, fetch state, timestamps, and refetch controls.

REACT QUERY · 05

5. The Query Cache

A cache stores successful query results in memory under their query keys. Components using the same key can observe the same cached data instead of each managing an unrelated copy.

["products"]
["product", 42]
["projects", page]

Visual Result

Query cache
Cached query["product", 42]

Product details are shared with components observing this key.

Component ACacheComponent B
A query key identifies cached data and allows observers to share updates.

By default, cached query data is considered stale immediately, so certain events can trigger background refetching. staleTime controls how long data remains fresh.

When a query has no active observers, it becomes inactive. The default garbage-collection time for inactive query data is five minutes.

REACT QUERY · 06

6. isLoading vs. isFetching

TanStack Query separates the status of the data from the activity of the query function.

FlagMeaning in v5
isPendingNo successful data exists yet.
isLoadingThe first fetch is currently in flight: isPending && isFetching.
isFetchingThe query function is running, including an initial fetch or background refetch.

This distinction lets an application keep old data visible while showing a smaller “Refreshing…” indicator during a background request.

Visual Result

Loading and fetching

First fetch

isLoading: trueisFetching: true

Ready

isLoading: falseisFetching: false

Refreshing

isLoading: falseisFetching: true
Background fetching can happen while successful cached data remains visible.

REACT QUERY · 07

7. Understanding isSuccess

isSuccess means the query has usable data. In TypeScript, checking the pending and error branches also narrows the successful data type.

function Products() {
  const { data, error, isPending, isError, isSuccess } = useQuery({
    queryKey: ["products"],
    queryFn: fetchProducts,
  });

  if (isPending) {
    return <p>Loading products...</p>;
  }

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

  // isSuccess is true here, and data is available.
  return (
    <ul>
      {data.map(function (product) {
        return <li key={product.id}>{product.name}</li>;
      })}
    </ul>
  );
}

Browser Result

localhost:5173/products

Products

  • Mechanical keyboard
  • USB-C hub
  • 27-inch monitor
isSuccess: true
After the pending and error branches are excluded, the successful result can render its data.

This is a component example, not yet a complete project: the provider setup and fetchProducts implementation come in the next practical lesson.

REACT QUERY · 08

8. Automatic Retries

A temporary network problem does not always mean the query should fail immediately. On the client, TanStack Query retries a failed query three times by default and uses an increasing delay between attempts.

useQuery({
  queryKey: ["products"],
  queryFn: fetchProducts,
  retry: 2,
});
ValueBehavior
retry: falseDo not retry.
retry: 2Retry at most two times.
retry: trueRetry indefinitely; use cautiously.
FunctionDecide based on the failure count and error.

Server-side queries default to zero retries so server rendering is not delayed. Applications should also avoid blindly retrying failures that are not temporary.

REACT QUERY · 09

9. Pagination

Pagination divides a large result into smaller pages. Include the current page in the query key so each page has its own cached result.

const result = useQuery({
  queryKey: ["projects", page],
  queryFn: function () {
    return fetchProjects(page);
  },
});

Visual Result

Paginated queries
["projects", 1]Page 1 cache["projects", 2]Page 2 cache
Changing the page changes the query key, so TanStack Query treats it as related but distinct cached data.

Without additional configuration, the UI can move back into a pending state when the key changes. TanStack Query v5 can use placeholderData: keepPreviousData to keep the previous successful page visible while the next page loads.

REACT QUERY · 10

10. React Query vs. RTK Query vs. SWR

All three tools help applications work with remote data, but they fit different ecosystems and styles.

ToolTypical fitCore style
TanStack QueryReact applications that want a dedicated server-state library without requiring ReduxQueries identified by keys and Promise-returning functions
RTK QueryApplications already using Redux Toolkit or wanting an API layer integrated with ReduxAPI slices, endpoint definitions, generated hooks, reducer, and middleware
SWRReact and Next.js applications wanting a compact hook-based cache and revalidation modelA key plus a fetcher function

There is no universal winner. Choose according to the application's existing architecture, required features, team familiarity, and preferred API.

Lesson Checklist

  1. Server data
  2. Pending, error, and success states
  3. Problems with manual state
  4. Purpose of TanStack Query
  5. Query caching
  6. isLoading and isFetching
  7. isSuccess
  8. Retries
  9. Pagination
  10. React Query, RTK Query, and SWR

Main idea: TanStack Query does not replace every kind of React state. It specializes in managing the lifecycle and synchronization of asynchronous server data.

Official Reading

← Back↑ Back to the top