Voiced by Amazon Polly |
Overview
React Query is a Javascript library for API calls, caching, re-fetching, and revalidating requests. This package provides a very good alternative to the useEffect hook. This library is very effective in handling server-state and asynchronous data fetching tasks. This also provides clean code and operations and reduces the code lines required for data fetching and caching operations.
Pioneers in Cloud Consulting & Migration Services
- Reduced infrastructural costs
- Accelerated application deployment
Hooks in React-Query
While working with React applications or other JavaScript frameworks, one of the most used and important features is requesting API for data and storing the data in the local state or variables and displaying the data in the UI.
Below is an example of fetching API data using useEffect in React:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import React, { useState, useEffect } from "react"; import axios from "axios"; function MyComponent() { const [data, setData] = useState([]); useEffect(() => { async function fetchData() { try { const response = await axios.get( "https://jsonplaceholder.typicode.com/posts" ); setData(response.data); } catch (error) {} } fetchData(); }, []); return <div>{ data?.map((post)=>( <div className=""> <h2>{post.title}</h2> <p>{post.body}</p> </div> )) }</div>; } |
The code above requires useState and useEffect imported from React. It uses a state to store data and determine whether the application retrieves data or the API has an error response. The pattern is repeated repeatedly for most of the application data retrieval logic. We can also notice the usage of the dependency array inside of useEffect so that the Api call is done only once when the component renders. The retrieved data is then shown in the Jsx format. This method of retrieving data is very long and repetitive.
Common Issues with Data Fetching in React
1) Data is shared between all application instances and can be modified by others.
2) Here, by default, we are not provided with the feature of caching our API response. This causes issues because we are repeatedly fetching data even when it’s not changing.
3) If the API call is done in the child component and the parent is re-rendered, re-renders for each parent re-render child and the useEffect and data fetching logic are called again. This is for bigger applications, can cause performance issues.
Finally, there is the issue of the local state, which often stores user preferences like theme and sidebar settings, and the remote state containing data fetched from APIs:
What the global state commonly looks like nowadays:-
1 2 3 4 5 6 7 8 9 |
const state = { theme: "light", sidebar: "off", followers: [], following: [], userProfile: {}, messages:[], todos:[], } |
One solution is to create your custom hook to handle data retrieval and processing. This is a perfectly valid solution. You can also share and manage this hook-on component center like Bit (GitHub).
That way, you can use it for whatever project you’re working on (either as a pure hook or as part of other reusable “smart components”).
Another solution, which we will dive into here, is React Query. This library will help you fetch, sync, update, and cache your remote data while reducing the amount of code you need to write by giving you two simple hooks and a utility function.
React Query Sample App
This small React app will use actions to get an array of strings from an API route.
You can insert new strings into the array using the provided form. It also opens the React Query DevTools to see the data in the cache in real-time.
In the above application shown, we are using the below code format to fetch the data, and you can see how the number of lines of code and logic has been significantly reduced.
1 2 3 4 |
const {status,data,error,isFetching} = useQuery('todos',async()=>{ const {data} = await axios.get('/api/data'); return data; }) |
useQuery Hook
The useQuery hook is a function to store data retrieval code in the React Query library. It takes an arbitrary key and an asynchronous function to retrieve data and return various values that you can use to inform the user of the current state of the application.
For example, let’s take refactor the useEffect code and make use of the useQuery hook provided by React-Query:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { useQuery } from "react-query"; function MyComponent() { const { isLoading, error, data } = useQuery("myData", async () => { const response = await fetch("https://my-api.com/data"); if (!response.ok) { throw new Error("Network response was not ok"); } const data = await response.json(); return data; }); if (isLoading) return "Loading..."; if (error) return "Error: ${error.message}"; return ( <div> {data.map((item) => ( <div key={item.id}>{item.name}</div> ))} </div> ); } |
Note that this code does not use the usual useState and useEffect hooks.
We are not importing any React hooks for data fetching and storing. The useQuery hook reduces the effort of writing long lines of fetching logic in useEffect and does the same task effectively but cleaner and more effectively than before.
Indeed, useQuery already has several values we can use in the application, such as isLoading, error response, and return data.
The difference between this code and the application above is that in the above application, we are using isFetching which tells us if we are currently re-fetching the data from API provided.
useMutation Hook
The useMutation hook is generally used to create/update/delete remote data. This function takes an asynchronous function to update your data (usually between POST, PUT, or DELETE requests) and returns a mutate function that you can call to trigger the mutation.
1 2 |
const [] = useMutation((text)=>axios.get('/Api/data',{text})); mutate('Learn about Query') |
You can also place optional functions that can be helpful and are mostly triggered when the function ‘mutate’ returns certain results, such as onSuccess and onError, which will only be triggered when the mutate function returns a specific result. In the example repo, you can see that I’m using the mutate function to put new data into the API when the form is submitted. I also reset the text input to empty when the mail request succeeds:
1 2 3 4 5 6 7 |
const [mutatePostTodo] = useMutation((text)=>axios.post('/api/data',{text}),{ onSuccess:()=>{ // Query Invalidations // queryCache.invalidateQueries('todos') setText('') } }) |
But if you try to insert new text in the demo app, you’ll notice that the to-do list doesn’t refresh.
To tell React Query to iterate over the task list, you need to remove the code above the setText function:
1 2 3 4 5 6 7 |
{ onSuccess:()=>{ // Query Invalidations queryCache.invalidateQueries('todos') setText('') } } |
queryCache.invalidateQueries will invalidate the cache with the todo keys and let React Query fetch the data again.
queryCache Tool
As you can see in the DevTools demo, React Query will cache the data fetched under the key task above. Still, it will automatically become stale after fetching unless you configure staleTime.
queryCache is a utility instance containing several functions that can be used to manipulate queries further. In the example, you see queryCache.
The invalidateQueries function makes React Query send a new request for a list of tasks.
Conclusion
React Query is an excellent library of hooks for handling data requests that remove the need to put remote data into the global state. You tell the library where your data comes from, and it takes care of caching, background updates, and stale data without any additional code or configuration.
React Query also removes the need for useState and useEffect hooks and replaces them with a few lines of React Query logic.
This will help keep your application maintainable, responsive, and fast in the long run.
Making IT Networks Enterprise-ready – Cloud Management Services
- Accelerated cloud migration
- End-to-end view of the cloud environment
About CloudThat
CloudThat is an official AWS (Amazon Web Services) Advanced Consulting Partner and Training partner and Microsoft Gold Partner, helping people develop knowledge of the cloud and help their businesses aim for higher goals using best in industry cloud computing practices and expertise. We are on a mission to build a robust cloud computing ecosystem by disseminating knowledge on technological intricacies within the cloud space. Our blogs, webinars, case studies, and white papers enable all the stakeholders in the cloud computing sphere.
Drop a query if you have any questions regarding React Query and I will get back to you quickly.
To get started, go through our Consultancy page and Managed Services Package that is CloudThat’s offerings.
FAQs
1. Why use React-Query?
ANS: – React query is a powerful tool that is very good in fetching Api data and caching so that the number of calls made to the API is limited if the values do not change. Not only that React-Query is also helpful for state management tools.
2. Why is React Query better than useEffect?
ANS: – React-Query will initially return the previously fetched data and then re-fetch when the data from the API call changes. Const {isLoading,isFetching,error,data,status} = useQuery(); This makes our code a lot simpler and easy to maintain.
3. Is React Query a framework or library?
ANS: – A React library enables us to fetch and manage data in React applications. It provides a powerful and easy use Api for fetching, caching, and updating data in React applications.
WRITTEN BY Rishav Mehta
Click to Comment