React-Query is a library that allows you to make requests and handle response metadata. To make a query, define a unique key and an asynchronous function to resolve data, as params of useQuery.
In this case, todos is the unique key, and fetchTodoList is the async function.
If you prefer to avoid booleans to handle the different states, a status variable is provided by the library:
As we can see, it’s very simple to implement and we can handle which element renders depending on the status.
React-query vs custom hook
Suppose we have a custom hook called useFetch:
This is already quite complex, and we did not even start to account for caching, invalidation and other features. The benefits of react-query library are:
- Avoid so many lines of code and complexity.
- It allows you to have queries ordered and set different parameters to each one.
- When the data becomes obsolete, it does a refetch in the background or you can do manual refetch (explained in the next section)
- It makes it easier for you to obtain the status and if isLoading, isError, etc.
- Provides an easier way to load-more, infinite scroll, dependent queries, paging, caching, and many more.
The list of benefits is extensive, and it can be extended further if we decide to explore the library more. Let’s go one step further to usages.
If we explore the documentation of the library, we can see a lot of parameters that can be set up to do many things. From making parallel, paginated, dependent, load-more and infinite scroll queries, to caching them. But I want to highlight something very important here, query results (via useQuery and similar hooks) will become “stale” immediately after they are resolved and will be refetched automatically in the background when they are rendered or used again. To change this, there are 2 ways to do it. First one, you can alter the default staleTime for queries to something other than 0 milliseconds. And the other way is using the third param of useQuery to set the manual in true. Besides that, we can use refetch to call when you want and update data. It could be depending on a variable or maybe in a callback.
Other importants things are:
If I have to implement multiple queries, I can rename the params that useQuery returns. On example 1, function doesn’t have parameters, but as we see on example 2, the async function needs one. If we only do this: getCharacters(characterSearch), we are executing the function. That’s why we resolved implementing it with an arrow function.
There’s many ways to optimize and options to set up react-query depending what you want to do. Explore this fantastic and useful library.
Should we replace the traditional custom hook to handle the response?
I think we can replace the traditional custom hook to make requests without using useState and useEffect, with many lines of code to return data in a success response, isLoading while is requesting, or error in that case. We could have a Hooks folder, in which we could have many files depending on the topic or setting of the queries. I also believe that react-query gives you the freedom to implement your queries in a way that fits your application architecture.