Data Fetching with Fetch API and Axios

In this module, we will learn how to fetch data in a React application using both the Fetch API and Axios. Fetching data from external sources (like APIs) is a common use case in React applications, and we will cover how to handle asynchronous requests, manage state, and work with APIs effectively.


Table of Contents

  1. Overview of Data Fetching in React
  2. Using the Fetch API in React
  3. Using Axios for Data Fetching
  4. Handling Errors in Data Fetching
  5. Using useEffect for API Calls
  6. Displaying Data in React Components
  7. Best Practices for Data Fetching
  8. Conclusion

1. Overview of Data Fetching in React

Data fetching is one of the most common operations in modern web applications. React doesn’t have a built-in solution for handling HTTP requests, but there are a variety of tools and methods to integrate external APIs. The two most popular methods for fetching data are:

  • Fetch API: A built-in JavaScript API for making HTTP requests.
  • Axios: A popular third-party library for handling HTTP requests that provides additional functionality over Fetch.

This module will explore both approaches in detail and how to effectively use them within React components.


2. Using the Fetch API in React

The Fetch API is a native JavaScript method for making HTTP requests. It returns a Promise that resolves to the Response object, which can then be converted into the desired format (JSON, text, etc.).

Basic Fetch Request Example

javascriptCopyEditimport React, { useEffect, useState } from 'react';

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

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((response) => response.json()) // Convert response to JSON
      .then((data) => {
        setData(data);  // Store the data in state
        setLoading(false);  // Stop the loading state
      })
      .catch((error) => {
        setError(error);  // Handle any errors
        setLoading(false);
      });
  }, []); // Empty dependency array means this runs once when component mounts

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>Fetched Data:</h1>
      <ul>
        {data.map((item) => (
          <li key={item.id}>{item.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default DataFetching;

Key Points:

  • The fetch function initiates the request and returns a Promise.
  • response.json() is used to parse the response body to JSON format.
  • useEffect is used to initiate the fetch request when the component mounts.
  • Error handling is done with .catch().

3. Using Axios for Data Fetching

Axios is a promise-based HTTP client for JavaScript that simplifies making HTTP requests. It provides an easy-to-use API with more advanced features than the Fetch API.

Installing Axios

To install Axios in your project, run:

bashCopyEditnpm install axios

Basic Axios Request Example

javascriptCopyEditimport React, { useEffect, useState } from 'react';
import axios from 'axios';

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

  useEffect(() => {
    axios
      .get('https://jsonplaceholder.typicode.com/posts')
      .then((response) => {
        setData(response.data);  // Axios automatically parses JSON
        setLoading(false);
      })
      .catch((error) => {
        setError(error);  // Handle error
        setLoading(false);
      });
  }, []);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>Fetched Data:</h1>
      <ul>
        {data.map((item) => (
          <li key={item.id}>{item.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default DataFetchingWithAxios;

Key Points:

  • Axios automatically handles response parsing, so no need to call .json() like with fetch.
  • The structure of the request and response is more intuitive and easier to use, especially for handling error responses.
  • Axios also has built-in support for request/response interceptors, which can be useful for adding headers, authentication, or logging.

4. Handling Errors in Data Fetching

In both Fetch and Axios, error handling is crucial to prevent the app from crashing when the API request fails.

Error Handling with Fetch

In the Fetch API, errors must be manually checked for failed responses (e.g., 404, 500).

javascriptCopyEditfetch('https://jsonplaceholder.typicode.com/posts')
  .then((response) => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then((data) => setData(data))
  .catch((error) => setError(error));

Error Handling with Axios

Axios automatically rejects the Promise when there is a network or HTTP error. It also provides an error object containing both response and request properties.

javascriptCopyEditaxios
  .get('https://jsonplaceholder.typicode.com/posts')
  .catch((error) => {
    if (error.response) {
      console.log('Error response:', error.response);
    } else if (error.request) {
      console.log('Error request:', error.request);
    } else {
      console.log('Error message:', error.message);
    }
    setError(error);
  });

5. Using useEffect for API Calls

useEffect is commonly used to trigger API calls when a component mounts or when dependencies change. By placing the fetch or Axios request inside useEffect, we can ensure the request is made once the component is rendered.

Example: Fetching Data on Component Mount

javascriptCopyEdituseEffect(() => {
  // Fetch or Axios request here
}, []);  // The empty dependency array ensures the request runs only once

6. Displaying Data in React Components

Once the data is fetched, you can easily render it by updating the state. Here’s an example of how to display a list of posts fetched from an API:

javascriptCopyEditreturn (
  <div>
    <h1>Fetched Data:</h1>
    <ul>
      {data.map((item) => (
        <li key={item.id}>{item.title}</li>
      ))}
    </ul>
  </div>
);

Here, we map over the data array and display the title of each todo post.


7. Best Practices for Data Fetching

  1. Avoid Making API Calls in Loops or Inside Other Functions: API calls should generally only be made inside useEffect or in response to user actions.
  2. Handle Loading and Error States: Always handle loading and error states to improve the user experience.
  3. Avoid Memory Leaks: Use cleanup functions within useEffect to prevent state updates after the component is unmounted.
  4. Throttle API Calls: Use techniques like debouncing or throttling for search functionality or frequent API calls.

8. Conclusion

In this module, we’ve learned how to fetch data from APIs in React using both the Fetch API and Axios. We also covered error handling, using useEffect for managing side effects, and best practices for fetching data in React.

By mastering these techniques, you’ll be able to build more dynamic, data-driven React applications that can interact with external services seamlessly.