React-query series Part 2: QueryClient configuration.
Tags: react, javascript, webdev, hooks
Published: 2021-08-20 12:57:54

Hey everyone!

I'm back, and with a little bit more confidence :muscle:. I am also very grateful for the encouragement I got from the previous post. Thank you!
In [**Part one: Basic react-query setup**](https://dev.to/nnajiforemma10/react-query-series-part-1-basic-react-query-setup-12g4), we talked about how to quickly setup `react-query` in our react project. We also touched on `QueryClientProvider` component, `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

  * [Intro](#point-0)
  * [The QueryClient configuration](#point-1)
    * [queries](#point-1a)
      * [retry](#point-1ai)
      * [staleTime](#point-1aii)
      * [cacheTime](#point-1aiii)
      * [refetchOnMount](#point-1aiv)
      * [refetchOnWindowFocus](#point-1av)
      * [refetchOnReconnect](#point-1avi)
      * [refetchInterval](#point-1avii)
      * [refetchIntervalInBackground](#point-1aviii)
      * [suspense](#point-1aix)

   * [mutations](#point-1b)
     * [retry](#point-1bi)
  * [Conclusion](#point-2)
  * [Credits](#point-3)


## Intro <a name="point-0"></a>
In this part, we will briefly talk about the configurations 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 <a name="point-1"></a>
You remember this snippet from the last post ?

```javascript
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` library or to put it better; it enables us 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 <a name="point-1a"></a>
The `queries` object lets us configure `react-query` behavior for our queries. According to the [documentation](https://react-query.tanstack.com/reference/useQuery), `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 <a name="point-1ai"></a>
The `retry` option takes either a `boolean`, `number` or `function` as it's 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` is given a `number` value, failed queries will retry until the failed queries count meets that number.
`retry` do also take a `function` as it's value. This `function` receives a failure count(number) and error as it's first and second argument respectively. This `function` must return a `boolean` to determine whether a query should be retried or not. 

```javascript
...

//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 ourselves if a query should be retried based on the number of failed attempts, type of error or both.

#### staleTime <a name="point-1aii"></a>
`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 it's value. `Infinity` as a value ensures that our data is never considered stale. When `staleTime` receives a `number`, the `number` is calculated as time in milliseconds after which the data is considered stale.


#### cacheTime <a name="point-1aiii"></a>
The `cacheTime` options receives either a `number` or `Infinity` as a value. It is the time in milliseconds that an unused/inactive cached data is allowed to remain in memory. When a 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, cached data are never cleaned from memory.
When `cacheTime` receives a `number` as it's value, this number is calculated as time in milliseconds after which, inactive/unused cached data is purged from memory.

#### refetchOnMount <a name="point-1aiv"></a>
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 exists and fresh in the cache; this is the control `refetchOnMount` gives us.
`refetchOnMount` accepts a `boolean` or the `string`: `"always"` as it's value.
If set to `false`, the query will not refetch on component mount by default. 
If value is set to `true`, the query is refetched if the data in cache is considered stale.
`"always"` as it's value will ensure that query is refetched regardless of whether cached data is stale or not.
 (Refer to `staleTime` to know when data is considered stale). 

#### refetchOnWindowFocus <a name="point-1av"></a>
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`, query will not be refetched on window focus. When set to `true`, 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<a name="point-1avi"></a>
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 use the control to determine whether we want our application to refetch queries once our users regain internet connection. 
`refetchOnReconnect` accepts a `boolean` or the `string`, `"always"`. By now, you can guess where this is going :wink:.
With `false` as a value, queries are not refetched on reconnection to the internet at all.
`true` lets 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<a name="point-1avii"></a>
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 <a name="point-1aviii"></a>
Would you like explicitly control the `refetchInterval` behavior for when users are not focused on our application ?`refetchIntervalInBackground` lets 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 <a name="point-1aix"></a>
`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 <a name="point-1b"></a>
Pheew :triumph: if you have gotten this far, I'm grateful. I'm a little :weary: 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. For any action that seeks to mutate our remote data, `mutations` should be used. Lets discuss the only item in the `mutations` object: `retry`.

#### retry <a name="point-1bi"></a>
`retry` as an option for the `mutations` object is similar to that for `queries`.
`retry` accepts either a `boolean`, `number` or `function` as it's value.
`false` as the value for `retry` ensures that failed mutations will not retry by default.
When `true`, failed mutations will retry infinitively(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 decide ourselves, when we want failed mutations to retry. This `function` must return a `boolean`.
```javascript
...

//function as value for retry in mutations

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

```



## Conclusion <a name="point-2"></a>
This post was a long one and I really 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 :sparkling_heart: if this post or part of it has helped you. Comments are welcomed too.
Follow me on [twitter @NnajioforEmma10
](https://twitter.com/NnajioforEmma10)


## Credits <a name="point-3"></a>
Image: [Logrocket: What is new in react-query 3 by Lawrence Eagles](https://blog.logrocket.com/whats-new-in-react-query-3/).

[React-query documentation](https://react-query.tanstack.com)


## Table of contents

  * [Intro](#point-0)
  * [The QueryClient configuration](#point-1)
    * [queries](#point-1a)
      * [retry](#point-1ai)
      * [staleTime](#point-1aii)
      * [cacheTime](#point-1aiii)
      * [refetchOnMount](#point-1aiv)
      * [refetchOnWindowFocus](#point-1av)
      * [refetchOnReconnect](#point-1avi)
      * [refetchInterval](#point-1avii)
      * [refetchIntervalInBackground](#point-1aviii)
      * [suspense](#point-1aix)

   * [mutations](#point-1b)
     * [retry](#point-1bi)
  * [Conclusion](#point-2)
  * [Credits](#point-3)