Getting started with React Query

React Query is an asynchronous global state manager. It is used to simplify the data fetching process and handle caching. It provides a straightforward way to manage the server.

· 6 min read
Mary Maina

Mary Maina

I am a frontend engineer passionate about building intuitive user interfaces. Tools: React, Next.JS, TypeScript, React Native, NodeJs


React Query Introduction

React Query is not a data-fetching library. When fetching data using the inbuilt fetch or Axios, a promise is produced. React Query relies on this promise to process the data.

If React Query is not a data-fetching library, what exactly does it do?

React Query is a library that is used to manage asynchronous server state out of the box and can be customized as the application grows. It is designed to simplify the data fetching process and caching in applications. It provides a straightforward way to manage the server data and keep it in sync with the user interface.

How does React Query compare with the old way of Data fetching?

React Query differs from the traditional method of data fetching using useEffect primarily in its approach and features. While both methods enable data fetching within React applications, React Query offers several advantages over the old way. React Query abstracts away much of the boilerplate code and complexity involved in managing data fetching manually with useEffect. It provides a cleaner and more concise API, reducing the need for developers to write custom logic for handling loading states, error handling, caching, and data prefetching.

The features of RQ

  1. Declarative Data Fetching: React Query provides hooks like useQuery and useMutation for declaratively fetching and mutating data. This simplifies the process of defining and executing queries, reducing boilerplate code.
  2. Automatic Query Caching: React Query automatically caches query results, optimizing performance by reducing unnecessary network requests. Cached data can be reused across components and shared between different parts of the application.
  3. Query Invalidation and Refetching: React Query offers built-in mechanisms for invalidating and refetching queries based on various triggers such as manual invocation, time intervals, or specific events. This ensures that data remains up-to-date and accurate.
  4. Optimistic Updates: React Query supports optimistic updates, allowing UI changes to be immediately reflected in the application interface before the actual mutation operation completes. This provides a smoother user experience by reducing perceived latency.
  5. Pagination and Infinite Loading: React Query includes features for handling pagination and infinite loading scenarios, making it easy to fetch large datasets incrementally without overwhelming the user or consuming excessive resources.
  6. Background Data Fetching: React Query supports background data fetching, enabling queries to be executed in the background without blocking the main thread. This helps improve performance and responsiveness, especially in scenarios involving complex data-fetching operations

Getting started with React Query - (Show me the code)

Let’s explore a straightforward example to demonstrate how easy it is to begin using React Query.

The initial step is to install the @tanstack/react-query library.

// npm
npm install @tanstack/react-query 

// yarn
yarn add @tanstack/react-query

pnpm add @tanstack/react-query

After the tanstack library is installed in our application. Create a provider and a client to use React Query. The React Query ClientProvider is a component provided by React Query that serves as a context provider for the React Query client instance. This component wraps your application and makes the client instance available to all components within its subtree via React’s context API.

import React from 'react';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement

const queryClient = new QueryClient();

  <QueryClientProvider client={queryClient}>
    <App />

Querying Data

React Query provides functionality for managing server states, achieved through the use of the useQuery hook. This hook is utilized for fetching data from your API, returning an object comprising the query’s status (loading, error, or success), the retrieved data, and methods for data refetching.

To understand how React Query performs data fetching, we will query a collection of posts from Jsonplaceholder API. Here’s an example of fetching data from the RESTful API using React Query and TypeScript:

In the above example, the useQuery hook is used to retrieve the posts and handle loading and error states. The getPosts function fetches the data using Axios. If data is loading or an error occurs, a message is displayed. Otherwise, the posts are rendered as a list.

Caching is managed by the useQuery hook. When you invoke useQuery with a key (in this instance, ‘posts’) and a fetch function (getPosts).

React Query executes the fetch operation and stores the outcome in a cache. The key you supply (‘posts’) serves as the identifier for this cache. If useQuery is invoked again with the same key while the data remains in the cache, React Query will retrieve the cached data instead of initiating a fresh fetch.

Executing this in your browser will result in the display of the list of post titles.


React Query is an asynchronous state manager.
The QueryKey uniquely identifies your query, so as long you call the query with the same key in two different places, they will get the same data.
Its smooth compatibility with TypeScript guarantees type security and improves the overall development journey.
Utilizing React Query empowers developers to create high-performing applications, delivering a seamless and interactive user interface.

Consider adopting React Query in your next project to unlock its full potential and elevate your application development process.

import { useQuery } from "react-query";
import axios from "axios";

interface PostProps {
 id: number;
 title: string;
 body: string;

const getPosts = async (): Promise<PostProps[]> => {
 const response = await axios("");

const Posts: React.FC = () => {
 const { isLoading, isError, error, data } = useQuery<PostProps[], Error>("posts", getPosts);

 if (isLoading) {
  return <div>Loading...</div>;

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

 return (
   { => (
    <li key={}>{post.title}</li>

export default Posts;


Mary Maina

I am a frontend devloper