Recently I had a chance to learn react-query, and after having used Angular and HttPClient for API calls for over an year I found this really amazing and easy to use as it provides bunch of different configurable parameters which solves a massive chunk of common problems for which we had to write functions manually.
A major problem that we all must have faced is CACHING! Traditionally, if we had to cache any data and prevent an API from being called again and again, we needed to store that data somewhere (in BehaviourSubject
or localstorage
, if you work with Angular) and every-time before calling an API we had to check if the data is already stored anywhere, if yes we could just use that or else go ahead and fetch data using API. A small code snippet for the same use case is provided
The above is an example of AppComponent
of angular where we are fetching the Super Heros data using getSuperHeros
function. This function first checks if the data is already stored in a BehaviourSubject
, and if it does it simply assigns the data to the superHeros
variable else it goes ahead and makes an API call to fetch the data and store it in the BehaviourSubject
.
Although there is no issue with the above implementation, one major question that arises is, "for how long the data will be cached?".
There are different answers for it based on what you use for storing the data.
If you've used BehaviourSubject
or anything similar to it that persists till the page is reloaded, the data will be cached till page is reloaded.
If you've used localstorage
that persists even if the page is reloaded, your data will be cached till the time you clear your localStorage. If you want your App to periodically look for changes, you'll have to store an interval along with the cached data and make API calls to see if the data from server has changed.
Looks a very tedious job... right?
You can achieve the above functionality with just two properties in react-query.
- cacheTime
- staleTime
Before we dive into above properties a little bit about useQuery
a very important hook from react-query
useQuery
The above image is an basic example of how we fetch data in React using useQuery
hook from react-query.
useQuery accepts multiple arguments first of which is queryKey
an unique key (which in our case is very important), second is queryFn
a function that is called to actually hit the endpoint, third is an object which contains multiple configurational options such as refetchOnWindowFocus
, cacheTime
, staleTime
, etc...
It also returns an object which when expanded contains multiple fields of which data
, isLoading
, isFetching
, being the important ones in context to this article
- data
data
is the same object that is returned from API, it is provided to us by useQuery
- isLoading
isLoading
is a boolean. It is set to true
when the data fetched from the API is being loaded and set to false
when the data is loaded completely
- isFetching
isFetching
is a boolean. It is set to true
when the API call starts and set to false
when the API call ends
Now let's have a look on the two properties that is used to achieve caching
cacheTime
cacheTime property accepts time(in ms) which determines how long the data from the API will be cached. By default it is set to 5 mins
.
In the above example, when we land on the App for the first time the following steps takes place in order to show the data
- useQuery hooks triggers
superHeroFetcher
function -
isFetching
is set totrue
-
isLoading
is set totrue
- API call takes place
-
data
is populated -
isFetching
is set tofalse
-
isLoading
is set tofalse
and then we're able to see the data fetched from API on screen.
But if we visit the App for the second time the following steps takes place
- useQuery hooks triggers
superHeroFetcher
function -
isFetching
is set totrue
-
isLoading
is set tofalse
- API call takes place
-
data
is populated -
isFetching
is set tofalse
-
isLoading
is set tofalse
See the difference?
Since the data is cached, using the unique key (queryKey
). isLoading
property is never set to true
and we won't see a Loading screen. However, an API call is still made and isFetching
is set to true
and then to false
and if there is any change in data the updated data object is returned.
To prevent this extra API call, staleTime
is the property that is to be used
staleTime
staleTime property accepts time(in ms) too and it determines for how long the data that is cached will be stale. By default it is set to 0
which means everytime you visit a page the API call will be triggered.
In the above image both staleTime
and cacheTime
are set to 3 mins each.
Cheers!🥂
Top comments (0)