0
0
ReactDebug / FixBeginner · 4 min read

How to Handle Loading State in React: Simple and Effective Approach

In React, handle loading state by using the useState hook to track if data is loading, and conditionally render a loading indicator or the content. This keeps the UI responsive and informs users while waiting for data or actions to complete.
🔍

Why This Happens

When fetching data or performing async tasks in React, the UI may try to render before the data is ready. Without tracking loading state, the component might show empty or broken content, confusing users.

jsx
import React, { useEffect, useState } from 'react';

function UserProfile() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/user')
      .then(response => response.json())
      .then(data => setUser(data));
  }, []);

  if (!user) {
    return <p>Loading user data...</p>;
  }

  return (
    <div>
      <h1>User Profile</h1>
      <p>Name: {user.name}</p>
      <p>Email: {user.email}</p>
    </div>
  );
}

export default UserProfile;
Output
TypeError: Cannot read property 'name' of null
🔧

The Fix

Use a loading state to track when data is being fetched. Show a loading message or spinner while waiting, then render the data once ready. This prevents errors and improves user experience.

jsx
import React, { useEffect, useState } from 'react';

function UserProfile() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('https://api.example.com/user')
      .then(response => response.json())
      .then(data => {
        setUser(data);
        setLoading(false);
      });
  }, []);

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

  return (
    <div>
      <h1>User Profile</h1>
      <p>Name: {user.name}</p>
      <p>Email: {user.email}</p>
    </div>
  );
}

export default UserProfile;
Output
User Profile Name: John Doe Email: john@example.com
🛡️

Prevention

Always initialize state properly and use a loading flag when fetching data or performing async actions. Use conditional rendering to avoid accessing data before it's ready. Consider using libraries like React Query for advanced loading and caching management.

Enable linting rules that warn about accessing possibly null or undefined values to catch these issues early.

⚠️

Related Errors

  • Cannot read property of undefined/null: Happens when rendering before data loads; fix by checking data existence.
  • Infinite loading state: Forgetting to update loading flag causes spinner to show forever; fix by setting loading false after data fetch.
  • State update on unmounted component: Happens if async fetch finishes after component unmounts; fix by cleanup with useEffect return function.

Key Takeaways

Use useState to track loading status and data separately.
Render a loading indicator while waiting for async data.
Avoid accessing data before it is loaded to prevent errors.
Update loading state to false once data fetch completes.
Consider cleanup in useEffect to avoid state updates on unmounted components.