Overview
React query gives us more powerful features like caching, pagination, lazy loading, server-side state management, fetching asynchronous data, etc. It can be used instead of writing complex
logic’s of Action and reducer in Redux.
React Query stores all its server state cache data in memory. As we know most people don’t like to stay on a website if it takes more than 5 seconds, and here the react query comes into the picture. React query uses the data from the cache to improve the performance of your app. It speeds up the execution speed, to maintain proper UI and people engagement.
For example, I have opened React Query official documentation, and it will try to cache data for 5 minutes (by default). And if I try to fetch this React Query official documentation seconds later, it will return me from the cache data. You can observe this in your development tool’s Network tab. And if there is a change in the server-side/back-end side, it may lack for a few more seconds/even a minute, when you try to fetch data for the second time.
What is server state management?
There are a few things, which you need to know about server state management before going further, such as:
- It requires async. API data for fetching and updating server state.
- It can be changed at any time and by anyone without having knowledge of it.
- It can become ‘out-of-date’ anytime if you don’t take proper care of it.
Difference between React Query and Redux?
- If you are working on an application which depends heavily on API calls that cache efficiently, optimized data fetching performance, etc then you can move with React Query.
- Instead of writing complex logic for state management like action and reducer, you can write useQuery(), useMutation(), etc in React Query with additional features.
- React Query is faster and lightweight than Redux, due to its small size and it focuses on async. data fetching and caching.
- If we wanna access any data coming from Rest API in Redux, we could access that data from the redux store directly or by using dispatcher logic. But in React Query, we can access data from the cache itself after getting data successfully from the API.
Installation :
To work with react query with your CRA app in ReactJS, just run the below code:
npm i react-query
To install the latest version of React Query, run the below code:
npm i @tanstack/react-query
Note: If you move to the latest version of React Query (i.e.: Tanstack Query), and if you were using ‘react-query/devtool’ then replace it by installing for Tanstack Query, otherwise it will throw an error.
for that run the below code:
npm i @tanstack/react-query-devtools
There are three main concepts to get started with React Query:
- Queries
- Mutations and
- Invalidate query
Queries:
The result of the query you get contains all the information such as data, configuration, headers, status, statusText, etc. The query which fetches data can be in a loading, success or error state.
The query result mostly depends on data or error state.
There are two things, which are important when working with Queries:
- queryKey (a unique key for a query, recommend writing in an array.)
- queryFn (it resolves the promise or throws an error)
Tips: If you want free rest API, then I recommend you to use free MockApi. It will allow you to create your free MockApi, where you can also perform operations like GET, POST, PUT, and DELETE.
MockApi : https://mockapi.io/projects
for example:
Let’s understand queryKey and queryFn in detail:
What is a Query Key?
As we know it is a unique key, which is used internally for refetching, caching, and sharing your queries in your whole application. The query key can be a string (i.e.: in the old version, we were using a string)
or
Array (i.e.: the latest version of react query uses query keys in the form of an array)
or
a nested object which uniquely describes the key. The recommended way is to use Array in queryKey. The 0’th index of every query key will define a unique key, and everything except the 0’th index will be something special(such as string, variables, etc.).
As said in official docs. “If your query function depends on a variable, include it in your query key”. It simply means what’s-ever we pass in queryKey except the 0’th index will show dependency.
Say, for example, to get clear-cut information:
In the above example, we have passed additional information (i.e.: carsId). It means, our queryFn depends on ‘carsId’. We can say that our queryFn will render whenever our carsId changes. It can be anything, (i.e.: string, variable or even a nested object)
The query will get automatically updated if the query key changes. But the ‘enabled’ option is more powerful than all. If it is set to ‘false’, the query will not be fetched at any cost.
What is a Query Function?
We can say that queryFn can be any function which returns the promise. The promise that it returns should resolve the promise or throw an error. ‘queryFn’ is a callback function, which is invoked when the asynchronous component renders.
We can also pass queryKey as a dependent parameter in the query function, as discussed earlier.
What is useQuery()?
useQuery() is a custom hook used in React Query, mainly used to fetch data with its built-in additional options. The result of usequery() will be ‘stale’ by default. There are many options which you can use as a third parameter in usequery() such as onSuccess, onError, refechInterval, keepPreviousData, staleTime, cacheTime, etc.
syntax:
let’s see which the other options the useQuery() hook provides for configuration:
Let’s see a few options one by one, for the remaining you can refer to the official docs.
- cacheTime:
- cacheTime: 5000,
The default cacheTime is 5 minutes or 300000 ms. It allows us to set Infinity or a number. If set to Infinity, it will disable garbage collection.
When the data becomes unused or inactive, it will become garbage collected after the specified duration. In short, cacheTime is used to cache data for a specified time after that it will become garbage collected.
- staleTime:
- staleTime: 30000, // 30 seconds
The default staleTime is ‘0’. As we go from the meaning of ‘stale’, it simply means not fresh. Say, for example, I have purchased a pack of Bread. It will be fresh for 3-4 days, but it will become dry/not fresh after that.
As we know, useQuery() will return ‘stale’ data by default.
Behind the scenes:
Let’s assume I have two components:- Home (static data) and
- CarsInfo (API data)
The data will be fresh, after setting ‘staleTime’ to 30 seconds. If you terminate from the ‘<Home/>’ component and come back to ‘<CarsInfo/>’, you may see that the data will be ‘fresh’ for 30 seconds and then it will become stale(1) and again fresh(0). You may see this change in React Query DevTool.
Stale query refreshes automatically in the background when the network is reconnected, the window is focused, or by config. of refetch option.
- retry:
- retry: 3,
It accepts the boolean/number or ‘(failureCount: number, error: TError) => number‘ function. It is useful when the API call throws an error. The default value of ‘retry’ is 3.
Behind the scenes:
Then see what happens when the promise is rejected, just open your Browser’s Development Tool and open the Network tab. Now, make some changes in your API link (i.e.: provide a wrong API link).You will be able to see, it will retry 3 times by default before throwing an error message in the UI. If it is set to ‘true‘, it will retry ‘infinitely‘. If it is set to ‘false‘, it will not recall the API.
- refresh Interval:
- refechInterval: 5000,
It accepts the number/false/function. If set to the number, it will re-fetch after the specified duration. It is mostly useful when the server data is being changed continuously.
- keepPreviousData:
- keepPreviousData true,
It is useful when you don’t want to show the spinner in the loading stage, instead of the spinner you want to show the old data in the UI.
- onSettled:This onSettled function will fire at any time. It’s the best feature of useQuery(), where we can write onSuccess and onError logic together. It will return either data or throw an error. I recommend using onSettled instead of writing onSuccess and onError separately.
Let’s see a demo of useQuery():
What is useQueries()?
It is similar to useQuery(), but the drawback of useQuery() was, we can fetch only one query or we need to use query two times useQuery(). useQueries() provides the feature of fetching more than one query at a time. It has all the options which useQuery() uses.
Let’s see an example so that you can get a better rich.
For example: Let’s suppose, I have two queries to be fetched at a time. So, for that, I have created one component:
Demo.js
Development ServicesGet Expert Assistance
Conclusion
I hope after reading this blog, you will be able to know the basics of React Query for data fetching, caching which is done by using hooks() of React Query, the proper use of Query Key and Function, etc. The syntax may defer, if you are using the old version or the latest version of React Query.
Let’s meet in the next session for more details about mutations (how to perform data updation, creating new response, etc.) and many more.