React Fetch

Ultimate Guide to Fetching Data from API using React Fetch with Clear Examples

July 20, 2022
Emmanuel Uchenna
React.js

The Fastest Way to Build React UI

Convert Figma designs to production-ready React.js code. Build stunning apps and landing pages faster than your peers and competitors.

Table of Contents
  1. Introduction to Fetching Data from API
  2. What is a REST API: Fetching data from API
  3. Advantages of RESTFul APIs: Fetching data from API
  4. Fetching data from API in React SPA
  5. Prerequisites to setup your CRA
  6. How to use the Fetch API to fetch data in React
    • How to use the fetch() method in React to fetch data from API
  7. How to use custom React hook (useFetch) to fetch data
  8. Steps to use the react-fetch-hook library
    • Using the custom React hook (useFetch) to fetch data from API
  9. How to use Axios to fetch data from API
  10. Steps to use use Axios to fetch data from API
  11. How to use the React Query to fetch data from API
  12. Steps to use React Query to fetch data from API
  13. Conclusion
  14. Videos on Fetching Data from API and Examples
  15. Further readings
react image

Introduction to Fetching Data from API

Often times, in fullstack web applications, you are required to either interact with a database; this can be a relational or non-relational database, or interact with an API. In such scenarios, you will need to send or request data through some network. Fetch allows you to send or get data across networks. As a React developer, you should be able to comfortably consume APIs in your React applications in order to build a full-fledged React application.

What is a REST API: Fetching data from API

REST API is an API (Application Programming Interface) which allows two software programs to communicate with each other. An API outlines the proper way for a developer to write a program requesting services from an operating system or other application.

REST stands for “Representational State Transfer” and it refers to an architectural style and approach to communication used in web services. REST APIs follow a structure known as the REST Structure for APIs. This consists of various rules that developers must follow when creating APIs.

Advantages of RESTFul APIs: Fetching data from API

The RESTful API architecture is advantageous over other similar technologies such as SOAP (Simple Object Access Protocol) because REST uses less bandwidth, making it more suitable for efficient internet usage. REST API is universal to language or platform as such, it can be consumed with any language or ran on any platform. RESTful APIs can also be built with programming languages such as JavaScript or Python.

Fetching data from API in React SPA

There are several methods to use REST APIs in a React application. These methods cut across using the built-in JavaScript fetch() API, to using your own custom React hook, to using third party libraries such as Axios, which is used to make an HTTP request from Node.js or XMLHttpRequests right from the browser.

When we make a data request from our application to an API, we must set up a state to store the data when it returns. Like Redux, a state is kept in a context object or a state management tool. But in order to keep things straightforward, we will store the returned data in the local state of React using useState React hook.

The next step is to provide a state to manage the loading phase of your application in order to enhance the user experience and a second state to manage the error in the event that something goes wrong

With that said, we therefore will have the following states:

const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

Where Should you use the Fetch Method in React Application?

In your React application, you should always make your fetch request in the componentDidMount lifecycle method in a class component or using the useEffect hook in a functional component.

This is due to the fact that when we fetch data from the backend, we perform an operation known as a side effect, which can result in a variety of outcomes for the same data fetching. The identical request can, for instance, return a success or an error. In React, we should avoid performing side effects directly within the component body to avoid inconsistencies.

In this case, we will fetch our data in the Hook like so:

componentDidMount() {
  fetch(`https://api.github.com/users/eunit99/repos`)
    .then(res => res.json())
    .then(
      (result) => {
        this.setState({
          isLoaded: true,
          items: result.items
        });
      },
      // Note: it's important to handle errors here
      // instead of a catch() block so that we don't swallow
      // exceptions from actual bugs in components.
      (error) => {
        this.setState({
          isLoaded: true,
          error
        });
      }
    )
}
// Note: the empty deps array [] means
// this useEffect will run once
// similar to componentDidMount()
useEffect(() => {
  fetch(`https://api.github.com/users/eunit99/repos`)
    .then(res => res.json())
    .then(
      (result) => {
        setIsLoaded(true);
        setItems(result);
      },
      // Note: it's important to handle errors here
      // instead of a catch() block so that we don't swallow
      // exceptions from actual bugs in components.
      (error) => {
        setIsLoaded(true);
        setError(error);
      }
    )
}, [])

A sample API response may look like so:

{
  "id": 350135946,
  "node_id": "MDEwOlJlcG9zaXRvcnkzNTAxMzU5NDY=",
  "name": "advance-loan",
  "full_name": "Eunit99/advance-loan",
  "private": false,
  "owner": {
    "login": "Eunit99",
    "id": 24845008,
    "node_id": "MDQ6VXNlcjI0ODQ1MDA4",
    "avatar_url": "https://avatars.githubusercontent.com/u/24845008?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/Eunit99",
    "html_url": "https://github.com/Eunit99",
    "followers_url": "https://api.github.com/users/Eunit99/followers",
    "following_url": "https://api.github.com/users/Eunit99/following{/other_user}",
    "gists_url": "https://api.github.com/users/Eunit99/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/Eunit99/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/Eunit99/subscriptions",
    "organizations_url": "https://api.github.com/users/Eunit99/orgs",
    "repos_url": "https://api.github.com/users/Eunit99/repos",
    "events_url": "https://api.github.com/users/Eunit99/events{/privacy}",
    "received_events_url": "https://api.github.com/users/Eunit99/received_events",
    "type": "User",
    "site_admin": false
  },
  "html_url": "https://github.com/Eunit99/advance-loan",
  "description": null,
  "fork": false,
  "url": "https://api.github.com/repos/Eunit99/advance-loan",
  "forks_url": "https://api.github.com/repos/Eunit99/advance-loan/forks",
  "keys_url": "https://api.github.com/repos/Eunit99/advance-loan/keys{/key_id}",
  "collaborators_url": "https://api.github.com/repos/Eunit99/advance-loan/collaborators{/collaborator}",
  "teams_url": "https://api.github.com/repos/Eunit99/advance-loan/teams",
  "hooks_url": "https://api.github.com/repos/Eunit99/advance-loan/hooks",
  "issue_events_url": "https://api.github.com/repos/Eunit99/advance-loan/issues/events{/number}",
  "events_url": "https://api.github.com/repos/Eunit99/advance-loan/events",
  "assignees_url": "https://api.github.com/repos/Eunit99/advance-loan/assignees{/user}",
  "branches_url": "https://api.github.com/repos/Eunit99/advance-loan/branches{/branch}",
  "tags_url": "https://api.github.com/repos/Eunit99/advance-loan/tags",
  "blobs_url": "https://api.github.com/repos/Eunit99/advance-loan/git/blobs{/sha}",
  "git_tags_url": "https://api.github.com/repos/Eunit99/advance-loan/git/tags{/sha}",
  "git_refs_url": "https://api.github.com/repos/Eunit99/advance-loan/git/refs{/sha}",
  "trees_url": "https://api.github.com/repos/Eunit99/advance-loan/git/trees{/sha}",
  "statuses_url": "https://api.github.com/repos/Eunit99/advance-loan/statuses/{sha}",
  "languages_url": "https://api.github.com/repos/Eunit99/advance-loan/languages",
  "stargazers_url": "https://api.github.com/repos/Eunit99/advance-loan/stargazers",
  "contributors_url": "https://api.github.com/repos/Eunit99/advance-loan/contributors",
  "subscribers_url": "https://api.github.com/repos/Eunit99/advance-loan/subscribers",
  "subscription_url": "https://api.github.com/repos/Eunit99/advance-loan/subscription",
  "commits_url": "https://api.github.com/repos/Eunit99/advance-loan/commits{/sha}",
  "git_commits_url": "https://api.github.com/repos/Eunit99/advance-loan/git/commits{/sha}",
  "comments_url": "https://api.github.com/repos/Eunit99/advance-loan/comments{/number}",
  "issue_comment_url": "https://api.github.com/repos/Eunit99/advance-loan/issues/comments{/number}",
  "contents_url": "https://api.github.com/repos/Eunit99/advance-loan/contents/{+path}",
  "compare_url": "https://api.github.com/repos/Eunit99/advance-loan/compare/{base}...{head}",
  "merges_url": "https://api.github.com/repos/Eunit99/advance-loan/merges",
  "archive_url": "https://api.github.com/repos/Eunit99/advance-loan/{archive_format}{/ref}",
  "downloads_url": "https://api.github.com/repos/Eunit99/advance-loan/downloads",
  "issues_url": "https://api.github.com/repos/Eunit99/advance-loan/issues{/number}",
  "pulls_url": "https://api.github.com/repos/Eunit99/advance-loan/pulls{/number}",
  "milestones_url": "https://api.github.com/repos/Eunit99/advance-loan/milestones{/number}",
  "notifications_url": "https://api.github.com/repos/Eunit99/advance-loan/notifications{?since,all,participating}",
  "labels_url": "https://api.github.com/repos/Eunit99/advance-loan/labels{/name}",
  "releases_url": "https://api.github.com/repos/Eunit99/advance-loan/releases{/id}",
  "deployments_url": "https://api.github.com/repos/Eunit99/advance-loan/deployments",
  "created_at": "2021-03-21T22:29:30Z",
  "updated_at": "2021-09-03T01:11:41Z",
  "pushed_at": "2021-04-17T07:58:20Z",
  "git_url": "git://github.com/Eunit99/advance-loan.git",
  "ssh_url": "git@github.com:Eunit99/advance-loan.git",
  "clone_url": "https://github.com/Eunit99/advance-loan.git",
  "svn_url": "https://github.com/Eunit99/advance-loan",
  "homepage": null,
  "size": 25511,
  "stargazers_count": 1,
  "watchers_count": 1,
  "language": "JavaScript",
  "has_issues": true,
  "has_projects": true,
  "has_downloads": true,
  "has_wiki": true,
  "has_pages": false,
  "forks_count": 0,
  "mirror_url": null,
  "archived": false,
  "disabled": false,
  "open_issues_count": 0,
  "license": null,
  "allow_forking": true,
  "is_template": false,
  "web_commit_signoff_required": false,
  "topics": [],
  "visibility": "public",
  "forks": 0,
  "open_issues": 0,
  "watchers": 1,
  "default_branch": "main"
}

The sample response above is from the GitHub REST API when I make a GET request to the following endpoint https://api.github.com/users/eunit99. It returns all the stored data about a user called eunit99. With this response, we can decide to render it whichever way we like in our React app.

Prerequisites to setup your CRA

Before you proceed with this tutorial, you must satisfy the following conditions:

  1. Node.js ≥v6 is installed on your local machine
  2. NPM is installed on your local machine
  3. You have an understanding of React.js
  4. You have an understanding of React hooks

In this guide, I shall walk you through how to fetch data from REST APIs in your React application using the following methodologies:

I will walk you through setting your React application to implementing all of the methods outlined above.

Let us jump right in 🎇🎆🎉

dancing panda

How to use the Fetch API to fetch data in React

The fetch() API (Fetch API) is an in-built JavaScript method which provides a better interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. Fetch API provides an easy to use way to fetch resources asynchronously across the network.

The Fetch API method can be basic as in the case below and making a request can really be simple to set up. However, The fetch() method always takes in a compulsory argument, which is the path or URL to the resource or API you want to fetch from and an optional parameter, like so:

fetch(url, options)

The options parameters allow you to specify the type of operation you want to carry out using HTTP methods like the GET method to request data from an endpoint, POST to send data to an endpoint, PUT to update data in an endpoint, or even DELETE to remove data from an endpoint.

A basic fetch request may look like so:

fetch('https://api.github.com/users/eunit99/repos')
  .then(response => response.json())
  .then(data => console.log(data));

How to use the fetch() method in React to fetch data from API

In this section, I shall walk you through how to use the fetch() method in your React app using React functional component. To get started, set up your React application using the below commands:

mkdir dev && cd dev && npx create-react-app rest-apis-tutorial && cd rest-apis-tutorial && npm start

What the commands above do are:

  • Creates a new directory called dev
  • Change directory into dev
  • Create a new React app called rest-apis-tutorial using the CRA command
  • Change directory into rest-apis-tutorial
  • Start your React app using npm start

You should get the following in your terminal upon completion of the commands above:

Compiled successfully!

You can now view rest-apis-tutorial in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.137.1:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully

Your React app will then start hot reloading your development environment and your app should be running on localhost:3000 by default.

image of React app

NOTE: We will make use of this app rest-apis-tutorial throughout this tutorial.

Using the fetch method to fetch from an API

In your App.js file, paste the following code:

import { useState, useEffect } from "react";

export default function App() {

  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(`https://api.github.com/users/eunit99/repos`)
      .then(response => response.json())
      .then((usefulData) => {
        console.log(usefulData);
        setLoading(false);
        setData(usefulData);
      })
      .catch((e) => {
        console.error(`An error occurred: ${e}`)
      });
  }, []);

  return (
    <>
      <div className="App">
        {loading && <p>Loading...</p>}
        {!loading && <p>Fetched data</p>}
      </div>
    </>
  )
}

In your console, you should have a response similar to this as a JSON response, which shows a list of repositories using from the endpoint https://api.github.com/users/eunit99/repos.

using the Fetch API to fetch
thinking gif

You might be wondering what each piece of code is doing?

In the code above, you used the fetch() method to request data from the resource endpoint (https://api.github.com/users/eunit99/repos) as seen inside the useEffect Hook. This operation returns a promise that could either resolve or reject. If it resolves, you handle the response using .then() block. However, it is important to note that at this stage, the returned data is a Response object, which is not the actual format that we need, although it is useful to check for the HTTP status and to handle errors. If the request fails, we use the .catch blog to handle the exception.

How to use custom React hook (useFetch) to fetch data

Since the introduction of hooks in React 16.8, you have the ability to use state and other React features without writing a class. In addition to this, React hook paved the way for developers like you to write their own custom hooks; thereby reducing repetition, spaghetti code, and helping you keep to software development best practices such as the DRY principle.

You may find that writing the useEffect hook and all of its boilerplate within each component where you want to fetch data becomes tiresome and time-consuming over time.

You can utilize a custom hook as a specific abstraction, which you can develop yourself from a third-party library, to reduce the amount of code you reuse (like you will be walked through, using the library react-fetch-hook).

Finally, you can greatly reduce the size of your components by using a custom hook to create your HTTP request. All you need to do is call the hook at the component’s top.

Steps to use the react-fetch-hook library

  • Install the library in your React application:npm i react-fetch-hook
  • Import the useFetch hook at the top in App.js like so:import useFetch from “react-fetch-hook”;

Using the custom React hook (useFetch) to fetch data from API

In your App.js file, paste the following code:

import useFetch from "react-fetch-hook";

export default function App() {


  const { isLoading, data, error } = useFetch("https://api.github.com/users/eunit99/repos");

  if (error) {
    return (
      <div>
        <p>Code: ${error.status}</p>
        <p>Message: ${error.statusText}</p>
      </div>
    )
  }

  if (!isLoading) {
    console.log(data);
  }


  return (
    <>
      <div className="App">
        {isLoading && <p>Loading...</p>}
        {!isLoading && <p>Fetched data</p>}
      </div>
    </>
  )
}

In your console, you should have a response similar to this as a JSON response, which shows a list of repositories using from the endpoint https://api.github.com/users/eunit99/repos.

using the Fetch API to fetch

How to use Axios to fetch data from API

Another approach to making requests with React is to use the library Axios which is a promise-based HTTP client for the browser and Node.js. Since Axios is promise-based, you benefit from async and await for asynchronous code that is easier to read. You can intercept and cancel requests using Axios, and it also contains a built-in function that offers client-side security against cross-site request forgery.

We will simply update our Fetch implementation in this example by first installing Axios using npm:

Steps to use use Axios to fetch data from API

  • Install the library in your React application: with either Yarn or NPM:npm install axiosoryarn add axios
  • Import the axios library at the top in App.js like so:import axios from “axios”;

What axios enables us to do is to use the exact same promise syntax as fetch – but instead of using our first then callback to manually determine whether the response is okay and throw an error, axios takes care of that for us.

import { useState, useEffect } from "react";
import axios from "axios";

export default function App() {

  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const getData = async () => {
      try {
        const response = await axios.get(
          `https://api.github.com/users/eunit99/repos`
        );
        setData(response.data);
        setError(null);
        console.log(data);
      } catch (err) {
        setError(err.message);
        setData(null);
      } finally {
        setLoading(false);
      }
    };
    getData();
  }, [loading]);

  return (
    <>
      <div className="App">
        {loading && <p>Loading...</p>}
        {!loading && <p>Fetched data</p>}
      </div>
    </>
  )
}

In your console, you should have a response similar to this as a JSON response, which shows a list of repositories using from the endpoint https://api.github.com/users/eunit99/repos.

using the Fetch API to fetch

How to use the React Query to fetch data from API

We can accomplish a lot more with the React Query module than merely get data. By eliminating errors and making our program feel faster, it offers support for caching and refetching, which has an impact on the entire user experience.

React Query offers a custom Hook that we can reuse to fetch data throughout our app, similar to the first approach. Install the library before before using it:

Steps to use React Query to fetch data from API

  • Install the library in your React application:npm i react-query
  • Import the React Query library at the top in index.js like so:
import { QueryClient, QueryClientProvider } from "react-query";

const queryClient = new QueryClient();
  • The client instance must then be passed to the QueryClientProvider we imported from react-query to wrap our parent component. Consequently, your index.js should look like so:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

import { QueryClient, QueryClientProvider } from "react-query";

const queryClient = new QueryClient();


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>
);
  • The next step is to fetch data using the useQuery Hook method from react-query, passing a distinct query key and the function that the query uses to do so:
import axios from "axios";
import { useQuery } from "react-query";

export default function App() {
  const { isLoading, error, data } = useQuery("posts", () =>
    axios(`https://api.github.com/users/eunit99/repos`)
  );
  console.log(data);
  return (
    <>
      <div className="App">
        {isLoading && <p>Loading...</p>}
        {!isLoading && <p>Fetched data</p>}
      </div>
    </>
  );
}

In your console, you should have a response similar to this as a JSON response, which shows a list of repositories using from the endpoint https://api.github.com/users/eunit99/repos.

using the Fetch API to fetch
glass

Conclusion

Almost all of the information you require about data fetching methods is covered in this tutorial. You were walked through how to retrieve data from a REST API.

You were also shown how to control various states, such as the loading and error stages. Now, you should now feel more at ease pulling data into your React application.

Try to spread this guide on the internet if you find it interesting.

Congratulations

Thinking of learning more? Find below some link to further tutorials:

thinking gif

Videos on Fetching Data from API and Examples

Fetch API Explained - Working with Data & APIs in JavaScript
JavaScript Fetch API || Fetch data from API and display data into browser.

Further readings

You can build UI faster than your competition with CopyCat. Just copy production-ready code generated directly from Figma designs using AI. As a result, you can focus on building interactions, animations, networking and everything else that will make you stand out. You can be an exceptional front end or react developer who develops UI quickly using CopyCat.

We know what it’s like to do redundant work. Our goal is to help you avoid development rework that leads to delivery delays. Let us help you find efficient ways to write quality code.

You’ll be 2X faster at developing UI. You’ll meet your deadlines and spend your time solving exciting challenges, too! Best of all, you’ll eliminate sprint delays and design inconsistencies.

Related Articles

  • React.js

    Render HTML Data to the DOM with React createElement

    Introduction React is an open-source JavaScript library developed by Facebook and it’s the most used and liked Frontend library by over 76% of developer respondents in The State of Frontend 2022. In this article, we'll take a deep dive into…

    November 29, 2022
  • React.js

    How to Add Toast Notifications to a React App Using React Toastify

    Introduction to Toast Notifications Notifications are ways to keep a user aware of the success or failure of their activity on a website and if not done correctly, the user may find your website overly uninteresting or have an unpleasant…

    October 14, 2022

Convert Figma To React

Convert Figma designs to production-ready React.js code. Build stunning apps and landing pages faster than your peers and competitors.

Convert Design to Code