Free ATS Friendly Resume Builder Online

Create Your Resume

Resume Builder

Resume Maker

Resume Templates

Resume PDF Download

Create Your Resume is a free online resume builder that helps job seekers create professional, ATS friendly resumes in minutes. Easily build, customize, and download modern resume templates in PDF format.

Our resume maker is designed for freshers and experienced professionals looking to create job-ready resumes. Choose from multiple resume templates, customize sections, and generate ATS optimized resumes online for free.

Create resumes for IT jobs, software developers, freshers, experienced professionals, managers, and students. This free resume builder supports CV creation, resume PDF download, and online resume editing without signup.

Back to React Js
Lesson 41 of 59

What Is Handling Loading and Error States in React? How to Manage API Race Conditions Correctly

Handling loading states, error states, and race conditions is essential for building reliable and professional React applications that interact with APIs. Loading states ensure users receive immediate feedback while data is being fetched, preventing confusion and poor user experience. Error states allow applications to fail gracefully instead of crashing or showing broken UIs. Race conditions occur when multiple API requests overlap and resolve out of order, leading to stale or incorrect data being rendered. This guide explains what loading states, error states, and race conditions are, how they happen in real-world applications, and how to handle them correctly using React hooks, cleanup logic, abort controllers, and best practices. It also includes code examples, comparisons, and production-level patterns used in scalable frontend systems.

Why Loading, Error Handling, and Race Conditions Matter

Modern React applications depend heavily on APIs. If loading states are ignored, users may think the app is broken. If errors are not handled, the UI may crash or behave unpredictably. If race conditions are not controlled, users may see outdated or incorrect data.

Production-grade applications such as data-driven user platforms must handle all three correctly to ensure stability and trust.

Handling Loading States in React

What Is a Loading State?

A loading state represents the period when an API request is in progress. It informs the user that data is being fetched.

Why Loading States Are Important

  • Improves user experience
  • Prevents blank or confusing screens
  • Gives feedback on slow networks

Basic Loading State Example


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

useEffect(() => {
  fetch("/api/users")
    .then(res => res.json())
    .then(result => {
      setData(result);
      setLoading(false);
    });
}, []);

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

This pattern is commonly used when rendering user-generated content or previews such as those found in structured document workflows.

Handling Error States in React

What Is an Error State?

An error state represents a failed API request due to network issues, server errors, or invalid responses.

Why Error Handling Is Critical

  • Prevents application crashes
  • Allows graceful fallback UI
  • Improves reliability in production

Error State Example


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

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

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

Proper error messaging avoids the “white screen of death” and is recommended in frontend stability best practices.

Combining Loading and Error States (Recommended Pattern)


if (loading) return <Loader />;
if (error) return <ErrorMessage message={error} />;
return <UserList users={data} />;

This conditional rendering pattern keeps UI logic clean and predictable.

What Are Race Conditions in API Calls?

A race condition occurs when multiple API requests are triggered, and their responses arrive out of order. The UI may render stale data as a result.

Real-World Example of a Race Condition

A user types quickly in a search input:

  • Request A: "r"
  • Request B: "re"
  • Request C: "rea"

If Request A finishes last, it overwrites the latest results.

Race Condition Problem Example


useEffect(() => {
  fetch(`/api/search?q=${query}`)
    .then(res => res.json())
    .then(setResults);
}, [query]);

This code is vulnerable to race conditions.

Fixing Race Conditions Using AbortController


useEffect(() => {
  const controller = new AbortController();

  fetch(`/api/search?q=${query}`, {
    signal: controller.signal
  })
    .then(res => res.json())
    .then(setResults)
    .catch(err => {
      if (err.name !== "AbortError") {
        setError(err.message);
      }
    });

  return () => controller.abort();
}, [query]);

This ensures only the latest request updates the UI.

Race Condition Fix Using Request Tracking


let requestId = 0;

useEffect(() => {
  const currentId = ++requestId;

  fetch(`/api/search?q=${query}`)
    .then(res => res.json())
    .then(data => {
      if (currentId === requestId) {
        setResults(data);
      }
    });
}, [query]);

Comparison: With vs Without Race Condition Handling

Aspect Without Handling With Handling
Data AccuracyUnreliableAlways correct
User ExperienceConfusingSmooth
Production SafetyRiskyStable

Common Mistakes Developers Make

  • Ignoring loading states
  • Not handling API failures
  • Triggering multiple requests without cleanup
  • Updating state after component unmount

Best Practices & Special Notes

  • Always handle loading, success, and error states
  • Cancel requests on component unmount
  • Prevent stale responses from updating state
  • Centralize API logic when possible

Testing race-condition scenarios using scenario-based assessments helps developers avoid subtle production bugs.

Final Takeaway

Handling loading states, error states, and race conditions is not optional in real-world React applications. These patterns ensure data accuracy, improve user experience, and protect applications from unpredictable failures. Mastering them is a strong indicator of senior-level frontend engineering skills.