React-query series Part 2: QueryClient configuration.

Emmanuel Nnajiofor
6 min readAug 20, 2021

--

Hey everyone!

I’m back and with a little bit more confidence 💪. I am also very grateful for the encouragement I got from the previous post. Thank you!
Part one: Basic react-query setup, we talked about how to quickly setup react-query up our react project. We also touched on QueryClientProvider components, queryClient, ReactQueryDevtools component and queryClient config object queryClientConfig. This will be a fairly long post. So, please use the links below to skip to sections relevant to you.

Table of contents

  1. Intro
  2. The QueryClient Configuration
  • queries
  • retry
  • staleTime
  • cacheTime
  • refetchOnMount
  • refetchOnReconnect
  • refetchInterval
  • refetchIntervalInBackground
  • suspense
  • Mutations
  • retry

3. Conclusion

4. Credits

Intro

In this part, we will briefly talk about the configuration settings object queryClientConfig we saw earlier. We will also look at what each key-value pair in the configuration does for our queries and mutations.

The QueryClient configuration

Do you remember this snippet from the last post?

import { QueryClient, QueryClientProvider } from 'react-query';

const queryClientConfig = {
defaultOptions: {
queries: {
retry: 2,
staleTime: 1000 * 30,// 30seconds
cacheTime: 1000 * 30, //30 seconds
refetchOnMount: "always",
refetchOnWindowFocus: "always",
refetchOnReconnect: "always",
refetchInterval: 1000 * 30, //30 seconds
refetchIntervalInBackground: false,
suspense: false,

},
mutations: {
retry: 2,
},
},

...

The queryClientConfig object provides us with the ability to tweak and override the default behavior of react-query the library or to put it better; it enables us to create our custom defaults both for queries and mutations across our application. This global configuration can also be overridden for each query or mutation instance in our application if need be (We will see how in the next article). Nested in the queryClientConfig object, is the defaultOptions object, which in turn has two objects; queries and mutations nested in it. The key-value pairs in these two objects( queries and mutations) are what we will be talking about.

queries

The queries object lets us configure react-query behavior for our queries. According to the documentation, queries can be passed in more configuration options but I chose this bit to keep things simple and flexible, also I believe they are the most relevant for the scope of this article.

retry

The retry option takes either a boolean, number or function as its value. When false, our unsuccessful queries are not retried by default. Passing in a true value ensures that our queries are retried infinitely (i.e. continued retries until the query gets successful). When retry given a number value, failed queries will retry until the failed queries count meets that number. retry do also take an function as its value. This function receives a failure count(number) and error as its first and second arguments respectively. This function must return a boolean to determine whether a query should be retried or not.

...

//function as value for retry

const queryClientConfig = {
defaultOptions: {
queries: {
retry: (failureCount, error) => {
//...do something with passed argument
}
...
},
},
...

function as a value of retry is aimed at giving us more granular control to determine if a query should be retried based on the number of failed attempts, type of error, or both.

staleTime

staleTime is time in milliseconds after which the returned data from a successful query is considered stale. staleTime accepts either a number or Infinity as its value. Infinity as a value ensures that our data is never considered stale. When staleTime receives a, the number is calculated as time in milliseconds after which the data is considered stale.

cacheTime

The cacheTime options receive either a number or Infinity as a value. It is the time in milliseconds that unused/inactive cached data is allowed to remain in memory. When cached data becomes unused or inactive, it will be cleaned up from the memory after this duration. When different cache times are specified, the longest one will be used.
If cacheTime is set to Infinity, and cached data are never cleaned from memory. When cacheTime receives a number as its value, this number is calculated as time in milliseconds after which, inactive/unused cached data is purged from memory.

refetchOnMount

When a component mounts and a query is run for the first time, the returned data from this successful query is cached. Sometimes, we may not want this same query to run again if the component remounts and the returned data from the previous call is still existed and fresh in the cache; this is what the control refetchOnMount gives us.

refetchOnMount accepts a boolean or the string: "always" as its value.
If set to false, the query will not refetch on the component mount by default. If the value is set to true, the query is refetched if the data in the cache is considered stale."always" as its value will ensure that the query is refetched regardless of whether cached data is stale or not. (Refer to staleTime know when data is considered stale).

refetchOnWindowFocus

This option is similar to refetchOnMount but for window focus.
We may wish to show our users fresh data whenever they switch their focus back to the browser tab where our application is being used; refetchOnWindowFocus helps with this. It accepts similar values as refetchOnMount : boolean or the string,"always". When refetchOnWindowFocus is set to false, the query will not be refetched on window focus. When set to true, the query is refetched only if cached data is stale. "always" will cause queries to refetch regardless of whether cached data is stale or not.

refetchOnReconnect

While using our application, users may lose internet connection. During this period, long or short as it may be, remote data may have changed.
refetchOnReconnect gives us the control to determine whether we want our application to refetch queries once our users regain an internet connection.

refetchOnReconnect accepts a boolean or the string, "always". By now, you can guess where this is going 😉. With false as a value, queries are not refetched on reconnection to the internet at all. true Let queries refetch on reconnection only if the data is considered stale. (again, check staleTime to understand when a cached data is considered stale).
"always" will ensure queries are refetched whether cached data is stale or not.

refetchInterval

We may want our application refetching queries at certain interval in time regardless of whether data is stale or not. This is very useful for rapidly changing remote data or for near real-time behavior for our application.
refetchInterval accepts either false or a number as it's value. false means that our queries will not refetch at interval. When a number is passed to refetchInterval as a value, this number is calculated as time in milliseconds. For example, 5000 as a value of refetchInterval means queries will be refetched every 5 seconds.

refetchIntervalInBackground

Would you like to explicitly control the refetchInterval behavior for when users are not focused on our application? refetchIntervalInBackground Let us do this. It accepts only boolean values. true as a value implies that queries will be refetched at interval (as set on refetchInterval) even when our application is not in focus. When false, queries will not refetch at interval when our application is not in focus.

suspense

suspense accepts only boolean values. When set to true, active queries will suspend and will throw a runtime error if an error occurs. With false, active queries will neither suspend nor throw a runtime error if an error occurs.

mutations

Pheew 😤 if you have gotten this far, I’m grateful. I’m a little 😩 myself. Hang in there, we are almost done.

The mutations object lets us configure react-query behavior for our mutations. Mutations are for create/update/delete actions to our server. Any action that seeks to mutate our remote data, mutations should be used. Let's discuss the only item in the mutations object: retry.

retry

retry as an option for the mutations object is similar to that for queries.
retry accepts either a boolean, number or function as its value.
false as the value for retry ensures that failed mutations will not retry by default. When true, failed mutations will retry infinitely (i.e. until a mutation is successful). If set to an number, e.g. 3, failed mutations will retry until the failed mutations count meets that number.
function as a value for retry enables us to decide ourselves, when we want failed mutations to retry. This function must return a boolean.

Conclusion

This post was a long one and I appreciate that you made it this far. In the next part, we will discuss data fetching with the useQuery hook. Thank you all for your support. Please give me a 👏 if this post or part of it has helped you. Comments are welcomed too.

Credits

Image: Logrocket: What is new in react-query 3 by Lawrence Eagles.

React-query documentation

--

--