Getting Started with React Query
Tags: javascript, react, nextjs, webdev
Published: 2022-04-18 17:55:38

What is React Query ? React Query is a library that gives state management ability for any kind of asynchronous data.

React itself didn't give any opinion on whether to use a way of data fetching. With React-Query there are some work need not to be done by a developer. (E.g maintaining loading state, error state, etc)

###### React Query has an impressive list of features

* caching
* deduping multiple request for the same data into a single request
* updating 'out of date' data in the background (provides stale data and refetching in the background, retrying )
* performance optimization like pagination, lazy loading
* memoizing query results
* prefetching the data
* mutations, which makes it easy to implement optimistic change

In this article am gonna discuss about how to fetch the data from an api using react-query.

React-Query provides a custom hook called 'useQuery' to fetch data. Underneath it maintains a lot more information about fetching the data like error,loading state and all.

I'm starting with new ReactJS app with create-react-app and after that install react-query

```
npm i react-query --save
```

I'd love to use axios but for the simplicity I'll go with fetch. I just cleaned my App.js and wrote the _fetchUsers_ function.

```
const fetchUsers = async () => {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');
    const data = await response.json();
    return data
}
```
Now instead of using this into a _useEffect_ or something, 
import useQuery from the react-query

```
import { useQuery } from 'react-query'
```

And now we can use it to fetch the data as 

```
const response = useQuery('users',fetchUsers)
```
Here, useQuery requires two arguments , first one is the key which should be unique across your whole code so that it can be identified. We can pass an array over here

Second argument is a function to fetch the data. I put _fetchUsers_ here.

We can pass an object as the third argument and it is optional which can alter some default configuration like _retry, retryDelay, enabled,cacheTime,onError_, etc.

Now our response has the following properties.

```
data,
error,
failureCount,
isError,
isFetchedAfterMount,
isFetching,
isIdle,
isLoading,
isPreviousData,
isStale,
isSuccess,
refetch,
remove,
status,
```

data - is the actual data we fetched.

status - will be a string or enum I'd say it will be either "loading", "error", "success" or "idle".

isLoading - is a boolean and it will be _true_ until the query function resolves or reject. after that it will be _false_. This would be more useful when it is loading for the first time and has no data yet.

isFetching - is a boolean and it will be _true_ until it refetching current data. 

For my example I'd be using data and status properties which are sufficient.

Now we can use it to display the data,

```
import React from "react";
import './app.css';
import { useQuery } from "react-query";
const fetchUsers = async () => {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  const data = await res.json();
return data;
};
const App = () => {
  const { data, status } = useQuery("users", fetchUsers);
  return (
    <div className="App">
      {status === "error" && <p>Error fetching data</p>}
      {status === "loading" && <p>Fetching data...</p>}
      {status === "success" && (
        <div>
          {data.map((user) => (
            <p key={user.id}>{user.name}</p>
          ))}
        </div>
      )}
    </div>
  );
};
export default App;
```

What I have done here is, check the status and display the data. This is a simple explanation of how we can use React Query useQuery hook. There are many other hooks as well.

Another version of using this useQuery, since we always use loading state and error state and all.

```
import React, {useState} from 'react'
import {useQuery} from 'react-query';


const fetchUsers = async () => {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  const data = await res.json();
return data;
};

function App() {
    const{data, isLoading, isError, error}= useQuery('users',fetchUsers)
    if(isLoading) {
        return <div>Loading...</div>
    }

    if(isError) {
        return <div>Something happened {error.message}</div>
    }
  return (
    <div className="App">
        Users
        <ul>
            {data?.map((user) => <li>{user.name}</li>)}
        </ul>
    </div>
  )
}

export default Users
```
Now we don't need to maintain the loading state, error state and all and that is being taken care of.

Hope this would be useful in your first step to react-query. Refer the official documentation for more information [React Query Official docs](https://react-query.tanstack.com/).