- Code with Ahsan - Newsletter
- Posts
- Memexplanation: React Suspense, lazy loading, and fallback
Memexplanation: React Suspense, lazy loading, and fallback
In this tutorial (and meme), we look at using Suspense and fallback for lazily loaded React components
Memexplanation: Using React Suspense and Fallback for lazy loading components
The meme 👇🏽
The explanation👇🏽
So in this quick tutorial, we'll use React’s lazy
imports and suspense to show a loading message while the component bundle is being loaded.
Setup
You'll need:
Step 1: Creating the React App
First, let's set up the app using the following command in your terminal:
npm create vite@latest
When asked, select JavaScript. And give it any name.
We have a simple React application structured into two main files: App.jsx
and Posts.jsx
. The app fetches a list of posts from a placeholder API and displays them. However, the twist lies in how the Posts
component is loaded and rendered.
Step 2: Replace the contents of App.jsx
import { Suspense, useState, lazy } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
const Posts = lazy(() => import("./Posts"));
function App() {
const [posts, setPosts] = useState([]);
const getPosts = async () => {
const resp = await fetch("https://jsonplaceholder.typicode.com/posts");
const json = await resp.json();
return json;
};
const loadData = async () => {
const postsFromServer = await getPosts();
setPosts(postsFromServer);
};
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<button onClick={loadData}>Load Data</button>
{posts.length ? (
<Suspense fallback={<h2>🌀 Loading...</h2>}>
<Posts posts={posts} />
</Suspense>
) : null}
</>
);
}
export default App;
In App.jsx
, React's lazy
function dynamically imports the Posts
component, which means Posts
won't be loaded until it's needed. This is particularly useful for improving the initial load time of your application. However, because Posts
is loaded lazily, we need a way to handle the loading state gracefully — that's where Suspense
comes in.
The Suspense
component wraps around Posts
and specifies a fallback UI (<h2>
🌀 Loading...</h2>
) that displays while waiting for the Posts
component to load. This provides immediate feedback to the user, making the loading process feel more responsive and less jarring.
Step 3: Replacing the contents of Posts.jsx
/* eslint-disable react/prop-types */
const Posts = ({
posts
}) => {
return (
<div>
<ul>
{
posts.map(post => <li key={post.id}>{post.title}</li>)
}
</ul>
</div>
)
}
export default Posts
Posts.jsx
is straightforward; it takes a list of posts and renders them. Thanks to lazy
and Suspense
in App.jsx
, this component's loading is optimized and doesn't impact the initial rendering performance of the application.
Explanation
By employing lazy
loading with Suspense
, we defer loading parts of our application until they are actually needed. This not only improves the load time but also conservatively uses resources, leading to a smoother experience for the end-user in low network conditions etc.
Conclusion
Just as you might use a fallback plan when hosting guests, using Suspense
and lazy
in your React applications provides a fallback UI during component loading. It's a simple yet effective way to enhance user experience, making your application feel faster and more responsive.
So, next time you're building a React app, ask yourself, "Do I have a fallback for this?" Your users might not see what's happening behind the curtain, but they'll definitely appreciate the seamless experience.
Don’t forget to subscribe for all the code snippets 🚀
Reply