Simplifying Data Loading in React with Suspense

What is React Suspense?

Suspense is a feature that allows components to communicate to React that they are waiting for some data. It’s not a data fetching library, nor is it a state management solution. Instead, Suspense enables components to render a fallback declaratively while waiting for an asynchronous operation to complete.

How to Use Suspense

To use Suspense, you need to wrap your component in a Suspense component and provide a fallback property. The fallback property is rendered while the component is waiting for data.


import { Suspense } from 'eact';

function MyComponent() {
  return (
    Loading...}>
      {/* component content */}
    
  );
}

Common Data Fetching Patterns

There are two common data fetching patterns in React: fetch-on-render and fetch-then-render. However, these patterns have limitations, such as leading to network waterfall problems. Suspense offers a better approach, known as render-as-you-fetch, which allows components to begin rendering immediately after triggering a network request.

Building a Sample App with React Suspense

To demonstrate the power of Suspense, let’s build a simple app that fetches data from an API and renders it to the DOM.

Structuring the API Folder

Our API folder will contain two files: wrapPromise.js and fetchData.js. The wrapPromise.js file is a wrapper that communicates with Suspense, while the fetchData.js file fetches data from an actual URL endpoint.


// wrapPromise.js
export function wrapPromise(promise) {
  let status = 'pending';
  let result;
  let suspender = promise.then(
    (r) => {
      status = 'uccess';
      result = r;
    },
    (e) => {
      status = 'error';
      result = e;
    }
  );
  return {
    read() {
      if (status === 'pending') {
        throw suspender;
      } else if (status === 'error') {
        throw result;
      } else {
        return result;
      }
    },
  };
}

Building Our App Components

We’ll create several components, including App.jsx, UserWelcome.jsx, and Todos.jsx. Each component will be wrapped in a Suspense component, which will handle the loading state.


// App.jsx
import React from 'eact';
import { Suspense } from 'eact';
import UserWelcome from './UserWelcome';

function App() {
  return (
    Loading...}>
      
    
  );
}

Managing Rendering Order with Suspense

To manage rendering order, we can nest Suspense components or use SuspenseList with a “reveal order” to specify the order in which components should render.


import { Suspense, SuspenseList } from 'eact';

function App() {
  return (
    
      Loading...}>
        
      
      Loading...}>
        
      
    
  );
}

Handling Errors in Suspense

We can use Error Boundary to handle errors in Suspense. This API helps catch errors within the Suspense tree without affecting the rest of the React DOM nodes.


import { ErrorBoundary } from 'eact';

function ErrorFallback({ error }) {
  return (

Something went wrong:

{error.message}
); } function App() { return (  Loading...}>    ); } 

Finishing Our App

After building our components and handling errors, we can run our app and see how Suspense simplifies data fetching and improves the user experience.

By leveraging Suspense, we can create more reactive and maintainable code, resulting in better UX and performance.

Leave a Reply