Lesson 29 — Fetch API in React (API Integration Step-by-Step)

🧭 Introduction

Modern React applications rarely work in isolation. Most real-world apps need to fetch data from APIs, such as:

  • User lists
  • Products
  • Surveys
  • Dashboard data

React uses the browser’s built-in Fetch API to communicate with backend services.

In this lesson, you will learn:

  • What Fetch API is
  • How to fetch data in React
  • How to handle loading & errors
  • How to display API data
  • Best practices and common mistakes

❓ What is Fetch API?

Fetch API is a built-in JavaScript API used to:

Make HTTP requests (GET, POST, PUT, DELETE) to a server.

It returns a Promise, which means it works asynchronously.


🧠 Why Use Fetch API in React?

✅ Built into the browser
✅ No external library required
✅ Supports all HTTP methods
✅ Works perfectly with React hooks


🧩 Basic Fetch API Syntax

fetch("https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));


🔄 Fetch API Flow

Component loads
 → fetch() called
 → server responds
 → data converted to JSON
 → state updated
 → UI re-renders


🧪 Simple Example: Fetch Data on Page Load

We’ll use a GET request to fetch data.


📄 Example Component

import { useEffect, useState } from "react";

const Users = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((response) => response.json())
      .then((data) => setUsers(data));
  }, []);

  return (
    <div>
      <h2>User List</h2>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

export default Users;


🧠 Why useEffect is Required?

  • Prevents infinite API calls
  • Runs once when component mounts
  • Ideal for fetching data
useEffect(() => {
  // API call
}, []);


⏳ Handling Loading State

Without loading state ❌
User sees blank screen


✅ With Loading State

const [loading, setLoading] = useState(true);

useEffect(() => {
  fetch("https://jsonplaceholder.typicode.com/users")
    .then(res => res.json())
    .then(data => {
      setUsers(data);
      setLoading(false);
    });
}, []);

if (loading) return &lt;p>Loading...&lt;/p>;


❌ Handling Errors Properly

Always handle errors to avoid crashes.


✅ Error Handling Example

const [error, setError] = useState(null);

useEffect(() => {
  fetch("https://jsonplaceholder.typicode.com/users")
    .then(res => {
      if (!res.ok) {
        throw new Error("Something went wrong!");
      }
      return res.json();
    })
    .then(data => setUsers(data))
    .catch(err => setError(err.message));
}, []);

if (error) return &lt;p>{error}&lt;/p>;


🧩 Complete Fetch Example (Best Practice)

import { useEffect, useState } from "react";

const Users = () => {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => {
        if (!res.ok) throw new Error("Failed to fetch");
        return res.json();
      })
      .then(data => setUsers(data))
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  }, []);

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

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

export default Users;


📤 POST Request Example (Create Data)

fetch("https://jsonplaceholder.typicode.com/posts", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "React Fetch API",
    body: "Learning Fetch API",
  }),
})
  .then(res => res.json())
  .then(data => console.log(data));


📌 Common HTTP Methods

MethodPurpose
GETFetch data
POSTCreate data
PUTUpdate data
DELETERemove data

⚠ Common Mistakes

❌ Forgetting useEffect
❌ Not handling errors
❌ Infinite API calls
❌ Updating state without cleanup


🎯 Best Practices

✅ Always handle loading & error state
✅ Keep API logic clean
✅ Use environment variables for URLs
✅ Move API logic to services (later lessons)


❓ FAQs — Fetch API in React

🔹 Is Fetch API better than Axios?

Fetch is built-in; Axios is more feature-rich. We’ll cover Axios next.


🔹 Can Fetch handle POST requests?

Yes, using method and body.


🔹 Should I use Fetch in every project?

Yes, for simple needs. Axios is preferred for advanced apps.


🔹 Where should API logic live?

Inside useEffect or separate service files.


🧠 Quick Recap

✔ Fetch API is built into the browser
✔ Used for API calls in React
✔ Works with useEffect
✔ Handles GET, POST, PUT, DELETE


🎉 Conclusion

The Fetch API is the foundation of API integration in React. Mastering it helps you connect your React app with real backend services confidently.

This lesson prepares you for advanced API handling and Axios integration 🚀


👉 Next Lesson (SECTION 6):
Lesson 30 — Axios in React

Leave a Comment