React Query
Tags: react, reactnative, javascript, webdev
Published: 2022-01-07 16:52:51

Hey there, I hope you are safe and well. Today I am going to write about React Query. What is a use of this library and Why you ever want to use it? 

I've been working with this library for past 6 months and I was always asking myself like Why I didn't know about it before? 


### Why? 

![React query why](https://media.giphy.com/media/cPKWZB2aaB3rO/giphy.gif)

I firstly going to share Why you ever want to use something like react query? In React Ecosystem. We have everything from state management like Redux, MobX to UI libraries like material UI, etc. 

But there is something that we always struggle especially me and that is API fetching. Yes that is true and I can bet you may have struggle with that too. 

See, API fetching needs to do lots of things other than just fetching and rendering the list in front of user. If you really care about User Experience You may have followed this pattern like,

It's our responsibility to acknowledge user what is happening behind the scene. Like fetching data (Show loading indicator). If something went wrong show Error message and so on. 

We always need to manually take care of all this stuff. Which I always struggle with that whenever I fetch APIs in components.

#### State Management. (Server States vs Local States) 

I have been reading Kent C. Dodds's blog and He has specifically mentioned that there are two types of States (Data) we need to handle. 

1) Server States 
2) Local States

They need to handle individually other than just using Global state management libraries like Redux library.

One of the best example of this situation is Chat Messaging System. 

In typically messaging app, You will see Loader whenever you send message and then the acknowledgment (Sent) and error (Message failed). In this situation you need to update states both sides. 

This can become complex as you try to add more functionalities. 

When I was learning React with Redux before, I thought redux will be the only one solution for all problems but then the day passed and I realised having a global state management is not sufficient to deal with all the challenges.  


#### Caching 

If you are beginner, You can ignore this but in simple words, Caching is a client side storage.
Whenever you request for data to server. Our browser cache (persists) data. Your browser will look into the cache before requesting data to server. This also allow us to manage caches by our own but there is no better way to implement that.

Caching perform a very crucial role in terms of scaling your app. You can learn more about caching on internet. 



### React Query 

React query is solution for all the challenges that I have mentioned above. It is a data fetching library or I should introduced as Missing Piece of React Ecosystem. React Query take care of everything from managing local and server states, Caching states, Managing various API states like Loading, Error, Data, etc.  


React Query wraps your app with Client Provider that manages caching and syncing of your states across all the components. (My favourite part). 😍

### Enough talk, let's show the example.

We are going to fetch posts from Server with help of react query. 

#### First we will wrap our App with `QueryClientProvider`. 

```javascript
   import { QueryClient, QueryClientProvider } from "react-query";
   const queryClient = new QueryClient();

   const App = () => { 
      return  <QueryClientProvider client={queryClient}>
       <Posts />
     </QueryClientProvider>
   }
```


#### We will use `useQuery` hook to fetch data.

This is just beginning.

```javascript
import { useQuery } from "react-query";

const Posts = () => {
    const { isLoading, error, data } = useQuery('repoData', () =>
     fetch('https://jsonplaceholder.typicode.com/posts').then(res =>
       res.json()
     )
   )
 
   if (isLoading) return 'Please wait...'
 
   if (error) return 'Error' + error.message
 
   return (
     <div>
        <h1> Posts of the Day </h1>
        { data.map(post => <h1 key={post.id}> {post.title} </h1>) }
     </div>
});
}
```


`useQuery` hook that take care of fetching data from the server. Something like `GET` method. Notice how this hook abstract the `loading` and `error` handling part.

> We didn't require to use `try catch` block here.

Key: key is unique for each request to identify each request uniquely.

Callback: This callback is callback that return async response. You can also use `Axios` here. 

#### Note:

Once this hook fetch the data from server. It stores that data in cache memory. So when component try to make same request again instead of asking from server it will return that response from `Cache Memory`.

You can also invalidate your cache storage if you need fresh data from server. All you need to use `useQueryClient` hook from `react-query`. 

We will see that example in next section. When we try to mutate data to server. 

Before we can talk about data mutation. You may notice that you don't need to use Global state management libraries like redux to manage server states throughout components. Because We have already use `Cache Memory`. That will syncs your data automatically without dispatching any actions or updating any states manually. This will be really helpful for a complex React Application.

Data Mutation 

Let's try send request of New Post to the server. We will use `useMutation` library to mutate data on server.

```javascript
import { useMutation, useQueryClient } from "react-query";
const NewPost = () => {
   const client = useQueryClient();
   const { mutate, isLoading } = useMutation(async (newPost) => {
    return await Axios.post("https://myblog.app/new", {...newPost}, {
    // register all the callbacks,
    onMutate: () => {
       // this will be called when you invoke mutation method
      // ie like temporary showing blog
    },
    onError: (error) => {
     // this will be called when your API request get failed.
    },
    onSettled: () => {
    // this will work either way. (Success, Fail)
    },
    onSuccess: (response) => {
      // this will be called when your API request get 
     // executed successfully. 
     client.invalidateQueries("posts"); // will refetch posts
    }
});
})

 const newPost = () => {
    // add new post 
    mutate({ id: `temp-name`, title: "My Blog", content: "The content goes here..." }); 
 }


}
```

As you can you can easily mutate data on server. Also the callbacks help you to acknowledge user what is happening without setting up manually. You can compare that this is easy way to fetch APIs than what we were doing before. 



The intention of writing this blog was let you know about this amazing library. Rather than manually handling the API Request sync with local states. which is can give you lots of headache.

I haven't covered everything of `react-query` library. You can prefer [documentation](https://react-query.tanstack.com/overview) for that. 

If you have read the entire blog. 
Thank you.

If you think there is something wrong in this blog. Feel free to correct me in comments. Share your thoughts in comments that are you going to use `react-query` or not. 

If you want to discuss something with me. You can reach me out on twitter. My DM is always open. I would love to help you. 

Twitter: [@iponikar](https://twitter.com/iponikar)