Understanding React Query

Simplifying Data Fetching in React Applications

Benny
Bina Nusantara IT Division
4 min readSep 29, 2023

--

Ferenc Almasi — unsplash.com

React Query is a powerful library developed by TanStack that simplifies data fetching and state management in React applications. It provides a straightforward way to manage remote data and keep it in sync with the UI. This article will introduce you to React Query, its key features, and how to get started using it in your React projects.

What is React Query?

React Query is a JavaScript library designed to simplify the complex task of data fetching and caching in React applications. It offers a set of hooks and utilities that enable you to manage data from various sources, including REST APIs, GraphQL, or even local state, effortlessly.

Key Features

  1. Declarative Data Fetching: React Query promotes a declarative approach to data fetching. You define queries and mutations using hooks like useQuery and useMutation. This leads to cleaner and more organized code.
  2. Automatic Caching: React Query includes a built-in cache that stores query results. It automatically updates data when mutations occur, ensuring your UI remains consistent.
  3. Background Data Sync: It can automatically refetch data in the background, keeping your data fresh without manual intervention.
  4. Pagination and Infinite Scrolling: React Query provides utilities for handling pagination and infinite scrolling effortlessly.
  5. Optimistic Updates: You can implement optimistic updates with ease, making your app feel more responsive.

Getting Started with React Query

Let’s dive into a basic example to see how simple it is to get started with React Query. The first thing you need to do is install the @tanstack/react-querylibrary. I will use npm for the execution.

npm install @tanstack/react-query

After the library is installed in our application, create a provider and client to use React Query. You can create it in the index.tsxfile in the srcfolder.

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

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

const queryClient = new QueryClient();

root.render
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
);

After that, you can immediately use React Query Hooks. Let’s apply it to the App.tsxscript.

import React from 'react';
import logo from './logo.svg';
import './App.css';
import { useQuery } from '@tanstack/react-query';

function App() {
const userData = useQuery(
['users'],
() => {
return fetch('https://jsonplaceholder.typicode.com/users').then(response => response.json());
},
{
enabled: false,
}
);

return (
<div>
<div>
<button onClick={() => userData.refetch()}>Get Users</button>
<div>
{userData.isFetching && (
<div>Fetching user data...</div>
)}
{userData.isError && (
<div>{`Error get data!!!`}</div>
)}
{userData.data && userData.data.length > 0 && userData.data.map((user: any) => (
<div>{user.name}</div>
))}
</div>
</div>
</div>
);
}

export default App;

In this example, we use useQuery to fetch a list of users. React Query handles the fetching state, error handling, and caching behind the scenes.

Get users with useQuery

When we click the Get Usersbutton, we are fetching data from the API. Because the amount of data is small, the fetching process becomes less visible because it is too fast.

Apart from useQuery, we also have useMutation where these hooks are almost the same as useQuery, but are used to mutate data. Below I show an example of its use. Just add this code.

import React from 'react';
import logo from './logo.svg';
import './App.css';
import { useQuery, useMutation } from '@tanstack/react-query';

function App() {
const userData = useQuery(
['users'],
() => {
return fetch('https://jsonplaceholder.typicode.com/users').then(response => response.json());
},
{
enabled: false,
}
);

const mutatePost = useMutation(
['posts'],
(newPost: any) => {
return fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify(newPost),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
}).then((response) => response.json())
}
)

return (
<div>
<div>
<button onClick={() => userData.refetch()}>Get Users</button>
<div>
{userData.isFetching && (
<div>Fetching user data...</div>
)}
{userData.isError && (
<div>{`Error get data!!!`}</div>
)}
{userData.data && userData.data.length > 0 && userData.data.map((user: any) => (
<div>{user.name}</div>
))}
</div>
</div>
<hr />
<div>
<button onClick={() => mutatePost.mutate({ title: 'First Post', body: 'First Post Body', userId: 1 })}>Add New Post</button>
<div>
{mutatePost.isLoading && (
<div>Adding new post...</div>
)}
{mutatePost.isError && (
<div>{`Error add new post!!!`}</div>
)}
{mutatePost.data && (
<div>{`Success add new post with title : '${mutatePost.data.title}'`}</div>
)}
</div>
</div>
</div>
);
}

export default App;

In the example above we use useMutation to add a new post.

Add new post with useMutation

Difference between useQuery and useMutation

  • Purpose: useQuery is for reading data, while useMutation is for modifying data.
  • Typical Use Case: useQuery is used when you want to fetch and display data, while useMutation is used when you want to make changes to that data.
  • Return Values: useQuery returns { data, error, isLoading, isFetching }, while useMutation returns { mutate, data, error, isError, isLoading, isSuccess }.
  • Error Handling: Both hooks handle errors, but useMutation provides additional features for handling optimistic updates and rollbacks in case of errors during mutations.

Conclusion

React Query is a valuable addition to the React ecosystem, making data fetching and synchronization easier than ever. Whether you’re building a small application or a large-scale project, React Query’s simplicity and powerful features will help you manage your data effectively.

By simplifying data management, React Query allows you to focus on building your application’s features and providing a better user experience. Give it a try in your next React project, and you’ll likely wonder how you managed data without it.

--

--