• Angular
  • React
  • NextJs
  • Sass

React Suspense Example

By Webrecto, October 08, 2023

Introduction

In this topic, we will learn about new <Suspense> features in React. The recent release of React 18 brought a lot of changes and improvements in Suspense to support server-side rendering. We can import Suspense from the react library. In the React programming model, Suspense makes the UI loading state a first-class declarative concept. In the latest version, React supports all when rendering on the server.

React Suspense Example

What is Suspense?

The <Suspense> lets you allow to display a fallback component until its children component loading has completely finished. It is used to manage asynchronous operations in the React application.

Syntax

<Suspense fallback={<Loader />}>
  <SomeComponent /> // use here component name
</Suspense>

React <Suspense> is a React technique or component that is used to suspend the component from rendering. It renders a fallback while the component is waiting for the data to be fetched.

Best Way to Use React Suspense Component

The <Suspense> is a new technique that provides convenience to our component "wait" for something before it can render. Some of the use cases where it is used are data fetching and waiting for images, scripts, and other asynchronous work to load.

<Suspense> does not detect when the data is fetched inside an Effect or Event handler. The Suspense component will be activated only by the Suspense-enabled data source.

Props for Suspense Component:

children: The <Suspense> boundary will display a fallback component when the children component takes too long time to render.

fallback: It is a lightweight placeholder view such as a loading spinner or any other loader component.

The <Suspense> automatically renders a fallback attribute when the children component is suspended, and it comes back to the children when the data is ready.

1) Displaying a fallback while content is loading

We can wrap any part of our application with a <Suspense> boundary. The React will display loading fallback until all the code and data needed by the children have been loaded.

import { Suspense } from 'react';
import Employee from './Employee';

export default function App() {
  return (
    <>
      <Suspense fallback={<Loader />}>
        <Employee /> 
      </Suspense>
    </>
  );
}

In the above example, The Employee component suspends while fetching the list of company employees. Until it is ready to render. The React switches the closest <Suspense> boundary above to show the fallback loading component. Then when the employee data loads in the Employee component, the React hides the Loading fallback and renders the Employee component with data.

2) Revealing content together at once

By default, the whole tree inside <Suspense> is treated as a single unit. For example, even if only one of these components suspends wait for some data, all of them together will be replaced by the loading spinner. Then, after all of them are ready to be displayed, they will all appear together at once.

import { Suspense } from 'react';
import Employee from './Employee';
import Customer from './Customer';

export default function App() {
  return (
    <>
      <Suspense fallback={<Loader />}>
        <Employee /> 
        <Customer /> 
      </Suspense>
    </>
  );
}

In the above example, The Customer and Employee components fetch some data from the API. However, they are grouped under a single Suspense boundary in the parent component. These components always 'pop in' together at the same time. The Components that load do not have to be direct children of the Suspense boundary.

<Suspense fallback={<Loading />}
   <MyDataList />
</Suspense>

For example, We can move the Customer and Employee components into a new MyDataList component, we find here, that it doesn't change the behavior. Because Customer and Employee share the same closest parent Suspense boundary.

3) Revealing nested content as it loads

When a component suspends, the closest parent <Suspense> component shows the fallback. This lets us nest multiple Suspense components to create a loading sequence.

import { Suspense } from 'react';
import Employee from './Employee';
import Customer from './Customer';

export default function App() {
  return (
    <>
      <Suspense fallback={<Loader1 />}>
        <Employee /> 
        <Suspense fallback={<Loader2 />}>
          <Customer /> 
        </Suspense>
      </Suspense>
    </>
  );
}

In the above example, The Employee component will display and will not wait for the Customer component to load.

The code will run in sequesnce:

  • 1: If the Employee component has not loaded yet, the first Loader is shown in place of the whole content area.
  • 2: Once the Employee component loading is finished, the first Loader is replaced by the employee data.
  • 3: If the Customer component has not loaded yet, the second Loader is replaced by the content.
  • 4: Finally, once the Customer component loading is finished, It replaces the second Loader.

4) Providing a fallback for server errors and client-only content

If we use one of the streaming server rendering APIs, React will also use the <Suspense> boundaries to handle errors on the server.

If a component throws an error on the server, React will not abort the server render. Instead, it will find the closest <Suspense> component above it and include its fallback.

On the client, React will attempt to render the same component again. If it error on the client too, React will throw an error and display the closest error boundary.

<Suspense fallback={<Loading />}
   <ErrorPage />
</Suspense>
function ErrorPage() {
  if (typeof window === 'undefined') {
    throw Error('Data should only render on the client.');
  }
  // ...
}

The server HTML will include the loading indicator. It will be replaced by the ErrorPage component on the client.

Complete Example

In the below code block, the Employee component is wrapped with a <Suspense> component which has a fallback prop. This means that the Employee component is waiting for some asynchronous operation to fetch employee data from the API. In the meantime, the React will render Loader component in the DOM to display some message. After completing the loading process the Employee component displays data.

Customer.js

import { useState } from "react";

function Customer() {
  return (
    <div className="App">
        <h2>Customer List:</h2>
        <p>1 - Mohan Singh</p>
        <p>2 - Ram Singh</p>
        <p>3 - Shailendra Gupta</p>
        <p>4 - Shubham</p>
    </div>
  );
}

export default Customer;

Employee.js

import { useState, useEffect } from "react";
import axios from "axios";

function Employee() {
    const [data, setData] = useState();

    useEffect(() => {
        const getData = async () => {
          axios.get('https://jsonplaceholder.org/users').then((response) => {
            setData(response.data)
          });
        };
        getData();
      }, []);
  return (
    <div className="App">
       <h3>Employee Name</h3>
       <table width="100%" border="1">
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
        </tr>
        {
          data && data.map((emp)=>{
             return(
              <tr>
                <td>{emp.firstname}</td>
                <td>{emp.lastname}</td>
              </tr>
             )
            })
        }
       </table>
    </div>
  );
}
export default Employee;

Loader.js

import { useState } from "react";

function Loader() {
  return (
    <div className="App"<
    <h3<Loader...</h3<
    </div<
  );
}

export default Loader;

App.js

import { useState, Suspense } from "react";
import './App.css';
import Loader from "./Loader/Loader";
import LoaderCustomer from "./Loader/LoaderCustomer";
import Employee from "./Employee/Employee";
import Customer from "./Customer/Customer";

function App() {
  
  return (
    <div className="App">
      <h2>React Suspense Example::webrecto.com</h2>
      <Suspense fallback={<Loader />}>
        <Employee/>
        <Suspense fallback={<LoaderCustomer />}>
            <Customer/>
        </Suspense>
      </Suspense>
    </div>
  );
}

export default App;

Find the print screen of the output.

React Suspense Example

Reference

Download Source Code