How to manage API calls in React ⚛️ 
Tags: react, javascript, beginners, webdev
Published: 2021-07-05 09:48:46

**React library** is well known for building rich and highly scalable user interfaces. There are many ways to fetch data from an **external API** in React. 

> Before you go through this blog be familiar with [React library](https://reactjs.org/) and [Application Programming Interface (API)](https://en.wikipedia.org/wiki/API).

In this blog, we will discuss different ways to _manage API calls_ in React. In the end, you will be able to choose the best approach based on the application requirements.

## 1. The Fetch API

**Fetch API** is built into most modern browsers on the window object (window.fetch) and enables us to make HTTP requests very easily.
 
The following code snippets show a simple example of using Fetch API in practice.

```javascript
import {useEffect} from "react";

const fetchUsers = () => {
// Where we're fetching data from
return fetch("http://www.abc.cd/test")
// We get the API response and receive data in JSON format
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch ((error) => console.error(error));}
```

The only goal of this function is to access the data and to convert the response into JSON using the `response.json()` method.
Here, the use of the `json()` method is to get the response object which is stored in data and used to update the state of users in our application.

The fact that Fetch is promise-based means we can also catch errors using the `.catch()` method. Any error encountered is used as a value to update our error’s state. 

Added to that, we make this request within the `useEffect()` hook with an empty dependencies array as the second argument so that our request is only made once, not dependent on any other data.
Here is an example how to use it in `useEffect()` hook:

```javascript
import {useEffect} from "react";
 
useEffect(() => {
	fetchData()
  }, []);
```
 
Isn’t this handy! Let’s see what other methods do 😃.

___
## 2. Axios Library

**Axios** is a Promise-based HTTP client for JavaScript which can be used in your _front-end application_ and your _Node.js backend_.
By using Axios it’s easy to send asynchronous HTTP requests to REST endpoints and perform _CRUD_ operations.

In this example, we have to first install Axios using _npm or yarn_ and then add it as an import to your parent component.

```
npm install axios
```

The following code snippets show an example of using Axios:

```javascript
import axios from "axios"

const fetchData = () => {
return axios.get("http://www.abc.cd/test")
   .then((response) => console.log(response.data));
}
```

Similar to the _Fetch API_, _Axios_ also returns a *promise*. But in Axios, it always returns a JSON response. The coding part is similar to the Fetch API, _except for shorter steps_ and _better error handling_.

> Check out the [official documentation](https://axios-http.com/docs/intro) for better knowledge.

___
## 3. Async-Await syntax

**Async/await** is a relatively new way to write asynchronous code synchronously.

The **async** keyword before a function has two effects:
- Make it always return a promise.
- Allows await to be used in it.

The **await** keyword before a promise makes JavaScript wait until that promise settles, and then:

- If it’s an error, the exception is generated.
- Otherwise, it returns the result.
 
The following is the code snippets :

```javascript 
async function fetchData() {
    try {
      const result = await axios.get("http://www.abc.cd/test")
      console.log(result.data));
    } catch (error) {
      console.error(error);
    }
  }
```

> When we use `useEffect()`, the effect function (the first argument) cannot be made an async function. For that, we can create a separate async function in our component, which we can call synchronously within useEffect and fetch our data accordingly.

___
## 4. Custom React Hook

A **custom Hook** is a JavaScript function whose name starts with _”use”_ and that may call other Hooks. The idea behind custom hooks is to extract component logic into reusable functions.

So let's call our custom hook: `useFetch`. This hook accepts two arguments, the _URL_ we need to query to fetch the data and an object representing the _options_ we want to apply to the request.
 
Alright! Now, let's see how easy it is to fetch data with our `useEffect()` hook. We are going to use the Fetch API to make our request. For that, we have to pass the URL and the options we want to retrieve. From there, we get an object that we can use to render our application.

```javascript
import { useState, useEffect } from 'react';
const useFetch = (url = 'http://www.abc.cd/test', options = null) => {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch(url, options)
      .then(res => res.json())
      .then(data => setData(data));
  }, [url, options]);
  return {data}
}
export default useFetch;
```

We can call whenever we need to fetch data inside our application.

```javascript
import useFetch from './useFetch';
  const { data } = useFetch( 'http://www.abc.cd/test' );
  console.log(data);
```
___
## 5. React Query Library

**React-query** is a great library that solves the problem of managing server state and caching in applications. 

> "It makes fetching, caching, synchronizing, and updating server state in your React applications a breeze”

Firstly, let’s install the required package

```
npm install react-query react-query-devtools
```

> Note: React Query also has its own [dev tools](https://react-query.tanstack.com/devtools) which help us to visualize the inner workings of React Query.

_React-query_ gives us a cache, which you can see below through the React Query Devtools. This enables us to easily manage the requests that we have made according to the key value that we specify for each request.

```javascript
import React from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider, useQuery } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";

const queryClient = new QueryClient();

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <FetchData />
    </QueryClientProvider>
  );
}

function FetchData() {
  const { data } = useQuery("UserData", () =>
    fetch("http://www.abc.cd/test").then((res) => res.json())
  );

  return (
    <div>
       // data you want to show
      <ReactQueryDevtools initialIsOpen />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```

In short, we just need to tell the library where you need to fetch the data, and it will handle caching, background updates, and refresh data without any extra code or configuration.

It also provides some hooks or events for mutation and queries to handle errors and other states of side effects which remove the need for `useState()` and `useEffect()` hooks and replaces them with a few lines of React Query logic.

> For better insights check out the [official documentation](https://react-query.tanstack.com/quick-start).

There are various other ways to manage data fetching such as [*SWR*](https://swr.vercel.app/), [*GraphQL API*](https://graphql.org/), but this blog post is not actually  explaining them in depth but you can check it out :)

___

That's all about it. By the way don't forget to check out the comment section of the following tweet. This might help you to choose the best approach.

{% twitter 1347978564251963392 %}

**Happy coding 😉**. Thank you for reading my blog 💖. 

Feel free to connect on **[Twitter](https://twitter.com/Adyasha8105)** :) 

<a href="https://www.buymeacoffee.com/Adyasha8105">
 <img width="100" src="https://res.cloudinary.com/practicaldev/image/fetch/s--8vsiOGpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/appcraftstudio/buymeacoffee/raw/master/Images/snapshot-bmc-button.png" class="loaded">
</a>
___