Introduction To React Query

Generally, when we make API calls to fetch data in a regular react application, we store all the fetched data in a global state that is made available to us by redux or useContext so that it is cached and we can fetch it again without having to wait for it to load, but as a developer, it takes a lot of manual configuration to set up.
React Query abstract away a lot of manual configuration with its APIs and handles data fetching, caching, synchronization with backend, and updating the server state like a champ.
In this blog, we'll be looking at the integration of react query in your react app and using hooks like useQuery for data fetching and useMutation for modifying operations on the server.
Basic Configuration
First things first, we need to wrap our application inside QueryClientProvider that we can import from react-query
Before we specify queryClient in the client object of QueryClientProvider we need to instantiate it. That's all we need for set up in index.js
//index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
ReactDOM.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
document.getElementById("root")
);
QueryClient essentially helps us to interact with the cached data from the queries we have made. It can return the data from the cache if the query still exists or if the specified staletime is not over and we obviously do not have to wait for the data to load in this process. Otherwise, it will fetch the most recent data.
useQuery Hook
In react query, useQuery hook is used to fetch data or perform any kind of read operations on the server. To make use of useQuery hook, you have to call it with
- A unique query key that is used to refetching and caching the data, so whatever data is returned from the promise we are going to cache it against this unique key
- An asynchronous function that returns a promise which ultimately resolves the data or throws an error
If we ever reuse the same key to fetch different data, it is going to overwrite all the previously cached data with the new data.
Let's take a look at how we actually fetch data with useQuery. In this example, we are going to be using Axios to fetch posts from a REST API.
import axios from 'axios'
import { useQuery } from 'react-query'
const fetchVideo = async => {
const response = await axios.get('http://localhost:3000/api/videos');
return response.data.posts;
};
const { data, isLoading, isError, error } = useQuery("post", fetchVideo);
useQuery returns an object full of important states that we can use for templating data, mount or unmount components, and many other operations. These returned properties are de-structured in the above example.
Among all the returned states, the most commonly used ones are
- data this property contains the returned data from the query
- isLoading is currently fetching data
- isError the query encountered an error
- error if the query is in isError state, the error property is returned with the error message
useMutation Hook
useMutation API is used in react query to make post requests for creating or updating data on the server, It also takes an asynchronous function that returns a promise very similar to useQuery hook.
useMutation hook returns a mutate function that we can use to trigger mutation from anywhere in the script. Mutate function can also take request body as an argument.
Usually, when we make a post request to the server, we send some data in the request body, mutate function helps carry the data to the parameter of the function provided in the hook and will ultimately be used as the request body in the post request.
Let's have a look at how to use useMutation hook. Here too, we use axios to make the API request.
import { useMutation } from "react-query";
const createComment= async commentData => {
const response = await axios.post("http://localhost:3000/api/videos/comments", commentData);
return response.data;
};
const { isLoading, isError, isSuccess, mutate } = useMutation(userSignup);
const commentHandler= data => {
mutate(data);
};
we can make use of the returned states isLoading, isError, and isSuccess for UI operations in react components.
Mutation doesn't need to be triggered immediately ( for eg: on page load) like useQuery does.
We can trigger the mutation at whichever point we want to, in the above example, we are triggering the mutation with an argument, when the commentHandler function is called.
Conclusion
React query is a tool that you absolutely should have in your toolset, because it just makes server-state data management extremely simple and in turn make the rest of your state management code simpler as well.
There are lots of useful tools in the documentation which I would encourage you to check out. This article was only meant to be an introduction because most of this stuff is already very well documented on the react query website.
Thanks for reading, If you liked it Please give it a like or tell me in the comments. Happy Coding 🌻
