← Back to Chapters

Suspense and Fallback

⏳ Suspense and Fallback

? Quick Overview

React Suspense helps manage loading states while components or data are being loaded asynchronously. The fallback UI is shown until the suspended content becomes available.

? Key Concepts

  • Suspense Boundary – A wrapper that pauses rendering.
  • Fallback – UI shown during loading.
  • React.lazy – Enables code-splitting.
  • Error Boundaries – Handle load failures safely.

? Syntax & Theory

Suspense works by suspending rendering when a component is not ready. React then displays the fallback UI until the promise resolves.

? Basic Suspense Example

? View Code Example
// App.js - Basic Suspense usage with lazy loading
import React, { lazy, Suspense } from "react";

const Profile = lazy(() => import("./Profile"));

function App() {
return (
<div className="text-center p-3">
<h4>React Suspense Example</h4>
<Suspense fallback={<p>Loading Profile...</p>}>
<Profile />
</Suspense>
</div>
);
}

export default App;

The fallback can be any React element such as text, spinner, or skeleton.

? Custom Fallback Components

? View Code Example
// LoadingSpinner.js - Reusable fallback component
import React from "react";

function LoadingSpinner() {
return (
<div className="d-flex justify-content-center align-items-center" style={{height: "100px"}}>
<div className="spinner-border text-primary" role="status">
<span className="visually-hidden">Loading...</span>
</div>
</div>
);
}

export default LoadingSpinner;
? View Code Example
// Using custom fallback inside Suspense
<Suspense fallback={<LoadingSpinner />}>
<Profile />
</Suspense>

⚙️ Nested Suspense Boundaries

? View Code Example
// Multiple Suspense boundaries for independent loading
<div>
<Suspense fallback={<div>Loading Sidebar...</div>}>
<Sidebar />
</Suspense>

<Suspense fallback={<div>Loading Main Content...</div>}>
<MainContent />
</Suspense>
</div>

? Suspense with Error Boundaries

? View Code Example
// ErrorBoundary.js - Handles component load errors
import React from "react";

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError() {
return { hasError: true };
}

render() {
if (this.state.hasError) {
return <h4 className="text-danger">Something went wrong while loading.</h4>;
}
return this.props.children;
}
}

export default ErrorBoundary;
? View Code Example
// Wrapping Suspense with ErrorBoundary
<ErrorBoundary>
<Suspense fallback={<LoadingSpinner />}>
<Profile />
</Suspense>
</ErrorBoundary>

? Use Cases

  • Code-splitting large React applications.
  • Progressive page rendering.
  • Lazy-loading dashboards or routes.

? Interactive Concept Diagram

Flow: Component Requested → Suspended → Fallback UI → Component Loaded → UI Rendered

? Interactive Simulator

Click the button to simulate a network request. Watch how the Fallback (Skeleton) appears instantly, and is then replaced by the Profile Component.

Ready to load...

? Live Output / Explanation

While the component is loading, users see the fallback UI. Once loaded, the actual component replaces the fallback seamlessly.

? Tips & Best Practices

  • Keep fallback UI lightweight.
  • Use skeletons for better UX.
  • Prefer smaller Suspense boundaries.
  • Always combine with Error Boundaries.

? Try It Yourself

  1. Create a reusable spinner component.
  2. Apply nested Suspense boundaries.
  3. Simulate loading delay with dynamic imports.