React-query series Part 4: Interacting with the cache using the useQueryClient hook.

Tags: react, javascript, webdev, hooks
Published: 2021-09-03 17:00:39

> Cover image by [**Lawrence Eagles**](https://blog.logrocket.com/author/lawrenceoputa/) in the article: [**What’s new in React Query 3**](https://blog.logrocket.com/whats-new-in-react-query-3/)

Hey everyone :wave:

It took a little while but I'm back again. I am always grateful for the encouragement. My special appreciation to my new followers:
@maxm, @sgrajan1, @ossygarcia, @mehzan07, @hi_im_ml, @fernado27, @gmazur92, and many others I cannot all mention for obvious constraints. I use this space to talk about frontend development, react-js especially. I intend to cover topics on [**strapi-js**](https://strapi.io) also.
In [**Part Three: Data fetching with the useQuery hook**](https://dev.to/nnajiforemma10/react-query-series-part-3-data-fetching-with-the-usequery-hook-4n22), we talked about how to fetch data using the useQuery hook, passing variable(s) to our query function, and lastly, overriding our global default configuration on a single query instance.

## Table of contents
  * [Intro](#point-0)
  * [The useQueryClient hook](#point-1)
    * [prefetchQuery](#point-1a)
    * [fetchQuery] (#point-1b)
    * [getQueryData](#point-1c)
    * [refetchQueries](#point-1d)
    * [getQueryState] (#point-1e)
    * [setQueryDefaults](#point-1f)
    * [clear] (#point-1g)
  * [Conclusion](#point-2)

## Intro <a name="point-0"></a>
If you have been following this series since [**Part One: Basic react-query setup**](https://dev.to/nnajiforemma10/react-query-series-part-1-basic-react-query-setup-12g4), you may have running through your mind these questions; I have learned how to set up this library, fetch data, but how does react-query reduce or eliminate my dependence on global store library like redux? How do I get data from a query instance in the `Foo.js` component to the `Bar.js` component without using a global store or by passing props around? What if I'd like to refetch a query initially called somewhere in my app-how do I get this cache to work for me? These are the questions I intend to answer in this part of the series. We are going to see how to interact with the cache from anywhere in our application. Some of the actions we can perform on the cache include but are not limited to prefetching a query, getting the current state of a query(ries), getting query data, setting a new query default, etc.

## The useQueryClient hook <a name="point-1"></a>

The `useQueryClient` hook (to not be confused with the `useQuery` hook or `QueryClient`) is our entry point to interacting with our query cache. The `useQueryClient` hook returns the instance of the current `QueryClient` of our application. We import `useQueryClient` from `react-query` thus
```javascript
import { useQueryClient } from 'react-query'
 
 const queryClient = useQueryClient()
```

`queryClient` in the snippet above provides us a couple of methods to interact with the cache. We destructure some of these methods inline thus

```javascript
import { useQueryClient } from 'react-query'
 
 const {
    prefetchQuery,
    fetchQuery,
    getQueryData,
    refetchQueries,
    getQueryState,
    setQueryDefaults,
    clear,
  } = useQueryClient();
```

There exist more methods from this object, but we are only taking this few I feel are most important. Do find time to look at a full list of these methods [**here**](https://react-query.tanstack.com/reference/QueryClient).


`prefetchQuery` <a name="point-1a"></a>

Do you need to fetch data in some part application before the user needs it? then `prefetchQuery` is what you need. 
`prefetchQuery` is used to prefetch a query before it is needed or rendered by `useQuery`. By using this asynchronous method, you will spare your users the dreaded loading spinners because the query data already exists, `react-query` only goes to refresh this data behind the scenes if it is stale as per your `QueryClient` configurations.

```javascript
await prefetchQuery(queryKey, queryFn)
```
`prefetchQuery` accepts a query key and a query function to prefetch.

```javascript
await prefetchQuery(queryKey)
```
You can also pass only a query key if you have a default query function set in your `QueryClient` configuration.

```javascript
await prefetchQuery(queryKey, queryFn, {
     staleTime: 10000,
})
```
`prefetchQuery` also takes a configurations object as a third parameter. The snippet above will prefetch a query only when the data is older than 10 seconds.

`fetchQuery` <a name="point-1b"></a>
`fetchQuery` is somewhat similar to `prefetchQuery`. It is used for fetching and caching a query. It either returns the data from the query or throws an error. If a query exists in the cache and data is not stale, it returns the data, else it goes on to fetch the query.

`fetchQuery` accepts a query key and a query function. 

```javascript
try {
   const data = await fetchQuery(queryKey, queryFn)
 } catch (error) {
   console.log(error)
 }
```
You can also pass a config object as a third parameter.

```javascript
try {
   const data = await queryClient.fetchQuery(queryKey, queryFn, {
     staleTime: 10000,
   })
 } catch (error) {
   console.log(error)
 }
/*
will fetch a query only when the data is older than 10 seconds.
*/
```
`fetchQuery` and `prefetchQuery` accepts configurations options just like the `useQuery` hook with exception of the following : `enabled`, `refetchInterval`, `refetchIntervalInBackground`, `refetchOnWindowFocus`, `refetchOnReconnect`, `notifyOnChangeProps`, `notifyOnChangePropsExclusions`, `onSuccess`, `onError`, `onSettled`, `useErrorBoundary`, `select`, `suspense`, `keepPreviousData`, `placeholderData`.

`getQueryData` <a name="point-1c"></a>

This method is used to get an existing query's data. You can get data from any existing query anywhere in your application. 

```javascript
const data = getQueryData(queryKey)
```
It returns the data if it exits or `undefined` if it doesn't.

```javascript
const data = getQueryData(queryKey)
```

`refetchQueries` <a name="point-1d"></a>

`refetchQueries` is used to refetch queries based on a certain condition. It accepts an optional query key and/or query filter as parameters.
Read more about query filters [**here**](https://react-query.tanstack.com/guides/filters#query-filters)

```javascript
// this will refetch all queries in the app:
 await refetchQueries()
 
 // this will refetch all stale queries:
 await queryClient.refetchQueries({ stale: true })
 
 /* this will refetch all active queries partially matching a query key "posts" */:
 await refetchQueries(['posts'], { active: true })
 
 // refetch all active queries exactly matching a query key:
 await refetchQueries(['posts', 1], { active: true, exact: true })
```

`getQueryState` <a name="point-1e"></a>

This function is used to get the state of an existing query. It returns `undefined` if this query does not exist. You can use this method to show loading, error, or success feedback for any query anywhere in your application.

```javascript
const state = getQueryState(queryKey)
//checking if this query is currently loading.
 console.log(state.isLoading)
```

`setQueryDefaults` <a name="point-1f"></a>

This method is used to set default options for a query. It accepts a query key and an options object.

```javascript
/*
sets a new 'cacheTime' default option for this query, overriding the global 'cacheTime' default option
*/

setQueryDefaults('posts', { cacheTime: 10000})
 
 function Component() {
   const { data } = useQuery('posts')
 }
```

`clear` <a name="point-1g"></a>

This methods simply clears all cache your application may be connected to.


## Conclusion <a name="point-2"></a>
We have seen that with the `useQueryClient` hook, we can start interacting with everything in our cache including getting a query's data, fetching a query refetching a query(ries), clearing our cache, etc.
In the next part, we will see how can start making mutating actions to our server i.e. the create/update/delete using the `useMutation` hook.

Thank you all for your support. If you are beginner and haven't written something, do that today! 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)

## Table of contents

  * [Intro](#point-0)
  * [The useQueryClient hook](#point-1)
    * [prefetchQuery](#point-1a)
    * [fetchQuery] (#point-1b)
    * [getQueryData](#point-1c)
    * [refetchQueries](#point-1d)
    * [getQueryState] (#point-1e)
    * [setQueryDefaults](#point-1f)
    * [clear] (#point-1g)
  * [Conclusion](#point-2)