How to Fetch API Data with useEffect Hook in ReactJS

How to Fetch API Data with useEffect Hook in ReactJS

Would you like to retrieve data from an API and display it on your React website?

You can accomplish this by utilizing the useEffect() hook, which allows you to send an asynchronous request using the fetch function in JavaScript.

In this article, we will guide you through the process of creating a ReactJS app that can fetch data from an API URL and display it on your website. Additionally, you will gain a better understanding of how the useEffect() hook operates in ReactJS.

What is useEffect() Hook in ReactJS?

In ReactJS, useEffect() is a built-in hook that allows you to perform side effects in functional components. Side effects refer to any code that needs to be executed outside the scope of the current component, such as fetching API data, subscribing to events, or manually manipulating the DOM.

The useEffect() hook is used to handle these side effects by providing a way to run code after the component has rendered or when specific dependencies have changed. It takes two arguments: a function and an optional array of dependencies.

The function specified as the first argument will be executed after every render. The second argument, the dependencies array, is used to control when the effect should run. If the dependencies array is empty ([]), the effect will only run once.

The syntax of the useEffect() hook in ReactJS is as follows:

useEffect(() => {
  // Code to be executed
  // Side effects, such as data fetching or DOM manipulation, go here

  // Optional cleanup function
  return () => {
    // Cleanup code, if necessary
    // This function will be executed when the component unmounts or before the next effect runs
  };
}, [dependency1, dependency2]);

Getting Started with API URL

In this example, we will utilize the API endpoint: https://random-data-api.com/api/v2/users?size=10&is_xml=true. By specifying the size=10 parameter, we ensure that only 10 users will be obtained.

If you open this URL in your browser, you will see data similar to the screenshot below.

react-api-data-sample

Based on this API response, we need to access the following information: id, first_name, last_name, avatar, and email as marked in the above screenshot. However, if you want any other fields then you can change the code accordingly.

In addition to this, we will enhance the functionality by displaying a “Loading...” text while the data is being fetched. Furthermore, any network errors that occur will be properly handled.

Let’s proceed with the implementation!

Step 1: Create React App

To begin, the first step is to create a React app. You can refer to the tutorial titled How to Create Your First ReactJS App: Hello World Example for guidance on creating the app. Follow the instructions provided in the tutorial to create the React app, and make sure to remove any unnecessary files to start with a clean slate as mentioned in the above tutorial.

Specifically, create the React app with the name api-request and follow the steps outlined in this tutorial. As well as remove any unwanted files and set up the project from scratch.

Step 2: Write Code for index.js

Open the index.js file and copy the code provided below. Obviously, I will provide an explanation of this code.

import React from "react";
import { createRoot } from "react-dom/client";
import { useState, useEffect } from "react";
import "./index.css";

const url = "https://random-data-api.com/api/v2/users?size=10&is_xml=true";

function FetchApiData() {
  const [isLoading, setIsLoading] = useState(true);
  const [isError, setIsError] = useState(false);
  const [users, setUsers] = useState([]);

  /* Load api data */
  const getUsers = async () => {
    await fetch(url)
      .then((resp) => {
        if (resp.status >= 200 && resp.status <= 299) {
          return resp;
        } else {
          setIsLoading(false);
          setIsError(true);
          throw new Error(resp.statusText);
        }
      })
      .then((resp) => resp.json())
      .then((users) => {
        setUsers(users);
        setIsLoading(false);
      })
      .catch((error) => console.log(error));
  };

  useEffect(() => {
    getUsers();
  }, []);

  if (isLoading) {
    return (
      <div>
        <h2>Loading...</h2>
      </div>
    );
  }

  if (isError) {
    return (
      <div>
        <h2>Error!</h2>
      </div>
    );
  }

  return (
    <React.Fragment>
      <div className="container">
        <h2>Users</h2>
        <ul className="profiles">
          {users.map((user) => {
            const { id, first_name, last_name, avatar, email } = user;
            return (
              <li key={id}>
                <img src={avatar} alt={first_name} />
                <div>
                  <h4>
                    {first_name} {last_name}
                  </h4>
                  <p>{email}</p>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
    </React.Fragment>
  );
}

const root = createRoot(document.getElementById("root"));
root.render(<FetchApiData />);

Step 3: Understanding the Code

Let’s understand code by breaking it into small parts.

Code Block 1: Importing Essential Libraries

First and foremost, we need to import the React, the React DOM library, as well as the required hooks (useState() and useEffect()). Additionally, an external CSS file (index.css) is imported. We will need index.css for styling our output.

import React from "react";
import { createRoot } from "react-dom/client";
import { useState, useEffect } from "react";
import "./index.css";

Code Block 2: Setting API Endpoint

Secondly, we need to define the URL of the API. As mentioned above, size=10 means we will extract random 10 users’ data.

const url = "https://random-data-api.com/api/v2/users?size=10&is_xml=true";

Code Block 3: Setting Up State Hooks

We need to create a functional component with the name FetchApiData(). Inside this component, we will define three state variables using the useState hook: isLoading, isError, and users. These variables will manage the loading state, error state, and fetched user data, respectively.

function FetchApiData() {
  const [isLoading, setIsLoading] = useState(true);
  const [isError, setIsError] = useState(false);
  const [users, setUsers] = useState([]);

Code Block 4: Fetching API Data Function Declaration

After, we are declaring getUsers() as an asynchronous function. It uses the fetch() function to send a request to the specified API URL. The response is checked for successful status codes (between 200 and 299), and if the response is successful, the data is extracted and set using the setUsers() function.

As well as the loading state is also updated. If there is an error during the fetch process, the loading state is set to false, the error state is set to true, and an error message is thrown.

/* Load api data */
const getUsers = async () => {
await fetch(url)
  .then((resp) => {
	if (resp.status >= 200 && resp.status <= 299) {
	  return resp;
	} else {
	  setIsLoading(false);
	  setIsError(true);
	  throw new Error(resp.statusText);
	}
  })
  .then((resp) => resp.json())
  .then((users) => {
	setUsers(users);
	setIsLoading(false);
  })
  .catch((error) => console.log(error));
};

Code Block 5: Calling Function to Fetch API Data with useEffect() Hook

The useEffect() hook is used to call the getUsers() to function when the component is first rendered. Since an empty dependency array ([]) is provided as the second argument, the effect will only run once.

useEffect(() => {
  getUsers();
},

Code Block 6: Handling Different States

After the useEffect() hook, there are conditional if statements to handle the different states. If the data is still loading (isLoading is true), a loading message is displayed. If there is an error (isError is true), an error message is displayed.

if (isLoading) {
return (
  <div>
	<h2>Loading...</h2>
  </div>
);
}

if (isError) {
return (
  <div>
	<h2>Error!</h2>
  </div>
);
}

Code Block 6: Show Fetched Data

Finally, we will write JSX code to display our fetched data. When there is no loading or error, the user data will be rendered. We utilize the map() function to iterate over the user data and create a list of user profiles. Each profile includes the user’s avatar image, name, and email.

return (
    <React.Fragment>
      <div className="container">
        <h2>Users</h2>
        <ul className="profiles">
          {users.map((user) => {
            const { id, first_name, last_name, avatar, email } = user;
            return (
              <li key={id}>
                <img src={avatar} alt={first_name} />
                <div>
                  <h4>
                    {first_name} {last_name}
                  </h4>
                  <p>{email}</p>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
    </React.Fragment>
  );

Related: See our guide on Top 6 Essential Rules for Writing JSX in React JS for more details.

Step 4: Enhancing the Output: Adding CSS Styling

Create a index.css file in a folder src/ and paste the below code into this file. This is an optional part, but we need to design a page to show user info in a grid format. However, you can use your own styling.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  width: 700px;
  margin: 1rem auto;
}

h2 {
  text-align: center;
}

.profiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  margin: 3rem auto;
}

.profiles li {
  width: 100%;
  display: flex;
  align-items: center;
  background: #fff;
  padding: 1rem 2rem;
  border-radius: 0.25rem;
  text-align: left;
}

.profiles img {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  margin-right: 1rem;
}

.profiles h4 {
  margin-bottom: 0.15rem;
}

.profiles a {
  color: hsl(210, 22%, 49%);
  text-transform: capitalize;
}

Step 5: Running App

To run this application, use the command npm start in Command Prompt/Terminal and navigate to http://localhost:3000/ in your web favorite browser. Upon doing so, you will be greeted with the following page, as depicted in the below screenshot.

react-api-output

Conclusion

This article serves as a comprehensive guide for you looking to fetch API data using the useEffect() hook in ReactJS, while also covering important aspects such as handling loading states, errors, and styling.


Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top