Suspense is a powerful feature of React that allows for more effective and user-friendly management of asynchronous processes. Handling asynchronous data fetching, code splitting, and rendering may become quite difficult as web application complexity grows. React Suspense addresses these issues by offering a declarative approach to manage asynchronous processes.
React Suspense allows components to suspend rendering while they wait for some asynchronous operation to complete, such as data fetching or code splitting. It was first introduced as an experimental feature but has since become a core part of React.
Let’s look at the following illustration to get a better understanding of React Suspense:
Let’s consider some real-world scenarios where React Suspense can be beneficial.
News website: Imagine a news website where articles are loaded asynchronously. React Suspense can help display a loading spinner while fetching the article content, providing a better user experience.
E-commerce product listings: In an online store, we often have a long list of products to display. With React Suspense, we can ensure that the product images and details load smoothly, even if they come from different sources or APIs. Users will see placeholders or loading spinners while data is being fetched, creating a seamless shopping experience.
Dashboard widgets: Consider a customizable dashboard with various widgets, like weather updates, stock prices, or social media feeds. React Suspense can help load each widget’s content independently, preventing one slow-loading widget from blocking the entire dashboard. Users can start interacting with available widgets while others load in the background.
Let’s look at the syntax of React Suspense:
<Suspense fallback={<Loading />}><SomeComponent /></Suspense>
In React Suspense, we use the <Suspense>
component to wrap an asynchronous operation. The fallback
prop defines what to render while the operation is in progress, and the content within the <Suspense>
component is the part that may have asynchronous loading; in this case, <SomeComponent />
.
React Suspense leverages the use of Suspense
components and the lazy
function for code splitting. Let’s look at an example where we fetch data from a fake API endpoint:
import React from 'react'; // This functional component, PostList, receives an array // of 'posts' as a prop and renders them. function PostList({ posts }) { return ( <ul> {posts.map((post) => ( // For each post, create a list item with a unique // key based on the 'post.id'. <li key={post.id}> {/* Display the 'post.title' within the list item. */} {post.title} </li> ))} </ul> ); } export default PostList;
Let's discuss the above code in detail.
app.js
fileLine 1: Import the necessary 'react'
library modules, useState
, useEffect
, and Suspense
.
Lines 4–11: Define a custom asynchronous hook called fetchPosts
. This hook fetches data from a given API endpoint, parses the response into JSON, and returns the data.
Line 14: Declare a lazy-loaded PostList
component using the React.lazy()
command. This component will be loaded asynchronously when required.
Lines 16–34: Define the main functional React component, App
. In order to maintain state and conduct asynchronous data fetching, it employs the useState
and useEffect
hooks. When the component is mounted, it uses the fetchPosts
hook to retrieve posts from the API.
Lines 25–33: While the PostList
component is loaded, the component renders a loading message inside the return statement using Suspense
. It renders the PostList
component when it has been loaded, passing the fetched posts as a prop.
Line 36: Export the App
component as the default export of the module so that it can be used anywhere in the application.
index.js
fileLines 1–3: We import the React
and ReactDOM
modules. The PostList
component is imported from the app.js
file.
Line 6: Select the HTML element with the id “root” using the document.getElementById("root")
command and assign it to the rootElement
constant. This is where the React component will be rendered.
Lines 9–12: The ReactDOM.render()
command is called to render the PostList
component inside the rootElement
. The component will be injected into the DOM and displayed on the webpage.
PostList.js
fileLine 1: Import the React
module from the 'react'
library.
Lines 5–18: Define a functional component, PostList
which is responsible for rendering a list of posts. It receives a single prop, posts
which is expected to be an array containing the post data.
Line 7: We create an unordered list (<ul>
) element to contain the list of posts.
Lines 8–15: We use the .map()
function to iterate over each post
in the posts
array. For each post
we create a list item (<li>
) element.
Line 11: Each list item has been assigned a key
prop. This key is required for React to render and update the component efficiently. We use the post.id
as the key in this case, assuming that each post has a unique identifier.
Line 13: Inside each list item, we display the post.title
. This assumes that each post
object has a title
property containing the post’s title.
Line 20: Finally, we export the PostList
component as the default export of this module.
Free Resources