Lesson 31 — Handling Loading & Errors in React (Best Practices)

🧭 Introduction

When working with APIs in React, loading and error handling are just as important as fetching data.
If your app does not properly handle these states, users may experience:

  • Blank screens
  • Frozen UI
  • Confusing behavior
  • App crashes

In this lesson, you will learn:

  • What loading and error states are
  • Why they are essential
  • How to handle them using Fetch & Axios
  • Best practices used in real projects

❓ What is Loading State?

Loading state represents:

The time when data is being fetched but not yet available.

During this time, the UI should:

  • Inform the user that something is happening
  • Prevent confusion

❓ What is Error State?

Error state represents:

A failure while fetching or processing data.

Common reasons:

  • Network issues
  • Server errors (500)
  • Unauthorized access (401)
  • Invalid API URL

🧠 Why Loading & Error Handling is Important?

Without handling ❌

  • Users see blank screens
  • App feels broken
  • Poor user experience

With proper handling ✅

  • Clear feedback
  • Professional UI
  • Better reliability

🧩 Basic State Setup

Every API-based component should have:

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


🛠 Handling Loading & Errors with Fetch API

📄 Example Component

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 users");
        }
        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;


🧠 Key Points (Fetch)

loading starts as true
finally() always runs
✔ Error message shown to user
✔ UI updates correctly


🛠 Handling Loading & Errors with Axios

Axios simplifies error handling.


📄 Axios Example

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

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

  useEffect(() => {
    axios
      .get("https://jsonplaceholder.typicode.com/users")
      .then((res) => setUsers(res.data))
      .catch(() => setError("Unable to fetch data"))
      .finally(() => setLoading(false));
  }, []);

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

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

export default Users;


🧩 Showing Better Loading UI

Instead of plain text:

&lt;p>Loading...&lt;/p>

You can use:

  • Spinners
  • Skeleton loaders
  • Shimmer effects

Example:

&lt;p>Fetching data, please wait ⏳&lt;/p>


🧩 Conditional Rendering Pattern

if (loading) return <Loader />;
if (error) return <ErrorMessage />;
return <DataList />;

This keeps code clean and readable.


⚠ Common Mistakes

❌ Forgetting to set loading to false
❌ Not showing error messages
❌ API call without try/catch
❌ Hard-coding error messages everywhere


🎯 Best Practices

✅ Always handle loading & error state
✅ Show user-friendly messages
✅ Keep API logic clean
✅ Centralize error handling (advanced apps)
✅ Avoid silent failures


❓ FAQs — Loading & Error Handling

🔹 Is loading state always required?

Yes, for any API call that takes noticeable time.


🔹 Should errors be shown to users?

Yes, but in simple and friendly language.


🔹 Can loading and error exist together?

No. One should always exclude the other.


🔹 Where should error handling live?

Inside the same component or in a reusable hook/service.


🧠 Quick Recap

✔ Loading shows progress
✔ Error handling prevents crashes
✔ Improves UX significantly
✔ Essential for real-world apps


🎉 Conclusion

Handling loading and error states is a core skill for every React developer. It transforms your app from a basic demo into a professional, user-friendly application.

After this lesson, your API integration is robust and production-ready 🚀


👉 Next Lesson (SECTION 6):
Lesson 32 — Environment Variables in React

Leave a Comment