How to Handle Loading State in React: Simple and Effective Approach
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.
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;
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.
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;
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
useEffectreturn function.