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 state | Server data |
|---|---|
| Modal visibility | Product list from an API |
| Selected tab | User account returned by a server |
| Input text | Search results |
| Temporary counter | Paginated 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:
| Status | Convenience flag | Meaning |
|---|---|---|
pending | isPending | No successful data is available yet. |
error | isError | The query ended with an error. |
success | isSuccess | Data 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
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
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.
| Flag | Meaning in v5 |
|---|---|
isPending | No successful data exists yet. |
isLoading | The first fetch is currently in flight: isPending && isFetching. |
isFetching | The 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
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
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,
});
| Value | Behavior |
|---|---|
retry: false | Do not retry. |
retry: 2 | Retry at most two times. |
retry: true | Retry indefinitely; use cautiously. |
| Function | Decide 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
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.
| Tool | Typical fit | Core style |
|---|---|---|
| TanStack Query | React applications that want a dedicated server-state library without requiring Redux | Queries identified by keys and Promise-returning functions |
| RTK Query | Applications already using Redux Toolkit or wanting an API layer integrated with Redux | API slices, endpoint definitions, generated hooks, reducer, and middleware |
| SWR | React and Next.js applications wanting a compact hook-based cache and revalidation model | A 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
- Server data
- Pending, error, and success states
- Problems with manual state
- Purpose of TanStack Query
- Query caching
isLoadingandisFetchingisSuccess- Retries
- Pagination
- 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.