# Supercharging Data Fetching in React with Custom Hooks and React-Query

## **Section 1: Setting up React Query**

React Query is a powerful library that simplifies data fetching and state management in React applications. It provides an elegant way to handle asynchronous operations and cache data for improved performance. Let's get started by setting up React Query in our project.

To install React Query, you can use the following command:

```powershell
npm install @tanstack/react-query
```

Once installed, you can import the necessary dependencies:

```javascript
import { useQuery } from "@tanstack/react-query";
import Cookies from "js-cookie";
```

The `useQuery` hook is provided by React Query and allows us to fetch data from an API. We'll also be using the `Cookies` library to handle authentication tokens.

Now, let's take a look at the `fetchApi` function:

```javascript
const fetchApi = async () => {
  const response = await request({
    url: "/your-end-point",
    method: "GET",
  });
  return response?.data?.data;
};
```

## **Section 2: Creating the Custom Hook**

Custom hooks are a powerful concept in React that allows us to encapsulate and reuse logic across multiple components. Let's create a custom hook called `useUsers` that leverage React Query to fetch user data.

```javascript
const GET_API_NAME = 'your-api-name';

const useApiQuery = () => {
  const token = Cookies.get("token");
  const { isLoading, isError, data, error, refetch } = useQuery(
    [GET_API_NAME],
    fetchApi, {
      enabled: !!token,
      onError: (error) => {
        console.error(error);
      },
    }
  );
  return { isLoading, isError, data, error, refetch };
};
export { useApiQuery };
```

The `useApiQuery` hook uses the `useQuery` hook from React Query to handle the data fetching. It takes an array of dependencies, in this case `[GET_API_NAME]`, to identify the query. Whenever the dependencies change, React Query will automatically re-fetch the data. The `fetchApi` function we defined earlier is passed as the second argument.

The `enabled` option is set to `!!token` to control whether the query should be enabled based on the presence of the authentication token. If there is no token available, the query will not be executed.

The `onError` option allows us to handle any errors that occur during the query. In this case, we simply log the error to the console, but you can customize the error handling as per your requirements.

The hook returns an object containing various values: `isLoading` indicates whether the data is currently being fetched, `isError` indicates if an error occurred, `data` contains the fetched data, `error` holds the error object if any, and `refetch` is a function to manually trigger a data re-fetch.

## **Section 3: Setting up Axios and Authorization**

To make API requests with authentication, we'll use Axios, a popular JavaScript library. Axios provides an easy-to-use API for sending HTTP requests and handling responses. Additionally, we'll configure Axios to include the authorization token in the request headers. Let's set it up.

First, install Axios and import the necessary dependencies:

```javascript
jsxCopy codeimport axios from "axios";
import Cookies from "js-cookie";
import { getApiURL } from "./baseURL";
```

Next, create an instance of Axios using the `axios.create` method:

```javascript
const client = axios.create({
  baseURL: getApiURL(),
});
```

The `baseURL` is set using the `getApiURL` function, which should return the URL of your API.

Now, let's define a function called `setAuthorizationHeader`:

```javascript
export const setAuthorizationHeader = () => {
  const token = Cookies.get("token");
  if (token) {
    client.defaults.headers.common["Authorization"] = `Bearer ${token}`;
  } else {
    delete client.defaults.headers.common["Authorization"];
  }
};
```

The `setAuthorizationHeader` function retrieves the authentication token from cookies using `Cookies.get`. If a token is available, it sets the `Authorization` header in the Axios client to include the token. If there is no token, the `Authorization` header is deleted.

To initialize the authorization header, call `setAuthorizationHeader`:

```javascript
codesetAuthorizationHeader();
```

Additionally, we can add an interceptor to update the authorization header before each request:

```javascript
client.interceptors.request.use((config) => {
  setAuthorizationHeader();
  return config;
});
```

The interceptor calls `setAuthorizationHeader` to ensure that the latest token is included in the request headers.

Finally, we can define a `request` function to handle sending requests:

```javascript
export const request = ({ ...options }) => {
  const onSuccess = (response) => {
    return response;
  };
  const onError = (error) => {
    return error;
  };
  return client(options).then(onSuccess).catch(onError);
};
```

The `request` function takes an options object and sends the request using the Axios client. It returns a promise that resolves with the response data on success or rejects with an error on failure.

## **Section 4: Usage**

Now that we have our custom hook `useUsers` set up, let's see how we can use it in a React component. We'll show an example of accessing the `data`, `isLoading`, and `refetch` properties returned by the `useApiQuery` hook.

```javascript
const { data, isLoading, refetch } = useApiQuery();
```

If the data is available, we can map over the `data` array and render a list item for each item in the data if it's an array.

## **Conclusion**

In this blog post, we learned how to build a custom hook using React Query for data fetching and Axios for handling API requests and authentication. By combining these powerful libraries, we can create efficient and reusable code for managing API calls in our React applications.

Feel free to customize and expand upon the code snippets provided to fit your specific use case.

If you found this blog post helpful, feel free to follow me on Twitter [**@**](https://twitter.com/thedeepanshuweb)[**thedeepanshuweb**](https://twitter.com/thedeepanshuweb), connect with me on LinkedIn [**Deepanshu Goel**](https://www.linkedin.com/in/deepanshuweb/)
