When using lazy loading (for example, with React.lazy() and Suspense), you can detect when data should be fetched and show a loading icon until both the component and its data are ready.
🔹 Approach 1 — Using React.Suspense with a Fallback
You can wrap your lazy component in a Suspense boundary with a loading spinner.
import React, { Suspense, lazy } from "react";
import Loader from "./Loader";
const UserList = lazy(() => import("./UserList"));
export default function App() {
return (
<Suspense fallback={<Loader />}>
<UserList />
</Suspense>
);
}
🌀 Here, Loader is shown while the component is being downloaded (lazy-loaded).
🔹 Approach 2 — Detecting Data Fetch in Component
Inside your lazy-loaded component, you can manage the data fetching state using useEffect and useState.
import React, { useEffect, useState } from "react";
const UserList = () => {
const [loading, setLoading] = useState(true);
const [users, setUsers] = useState([]);
useEffect(() => {
setLoading(true);
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((data) => {
setUsers(data);
setLoading(false);
});
}, []);
if (loading) return <p>Loading data...</p>;
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
);
};
export default UserList;
🔹 Approach 3 — Combine Both (Best Practice)
Use Suspense for component lazy loading
and useState/useEffect for data lazy fetching.
This way, you can show a single unified loader while:
- Component is being loaded (via
React.lazy) - Data is being fetched (inside component)
✅ In Summary
- Use
Suspense→ for component loading detection - Use
useState + useEffect→ for data fetching detection - Combine both → show loader until both are ready