DEV Community

Ayush Vishwakarma
Ayush Vishwakarma

Posted on

Caching the React Query Way!

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

Caching in Angular

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.

  1. cacheTime
  2. staleTime

Before we dive into above properties a little bit about useQuery a very important hook from react-query

Data Fetching using useQuery

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

  1. useQuery hooks triggers superHeroFetcher function
  2. isFetching is set to true
  3. isLoading is set to true
  4. API call takes place
  5. data is populated
  6. isFetching is set to false
  7. isLoading is set to false

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

  1. useQuery hooks triggers superHeroFetcher function
  2. isFetching is set to true
  3. isLoading is set to false
  4. API call takes place
  5. data is populated
  6. isFetching is set to false
  7. isLoading is set to false

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.

cacheTime and staleTime in use

In the above image both staleTime and cacheTime are set to 3 mins each.

Cheers!🥂

Top comments (0)