Managing Asynchronous Code in React

Meet Suspense & Error Boundaries

Igor Sukharev
The Startup
3 min readSep 6, 2020

--

Photo by Benjamin Voros on Unsplash

Introduction

Traditionally, dealing with asynchronous code in React has required some boilerplate:

  • Make a wrapper component to show a pending or rejected state.
  • Make our components keeping track of pending and rejected state and inform the wrapper component about state changes.

But ideally, we want:

  • To care only about the fulfilled state in our components.
  • To abstract away the pending and rejected state.

Here, I am going to show you how to achieve just that and how to structure asynchronous code in a modern way.

Tools

We are going to use the Suspense component and Error Boundaries. They have been available since React 16.6.

Suspense

The Suspense component will display a fallback user interface until all of its children will have their state fulfilled:

Error Boundary

From now on, I am going to use the Exception component as an Error Boundary implementation. It will display a fallback user interface if any of its child components will throw an exception:

Example

Suppose we want to fetch users’ data from a remote resource:

I will use makeSuspendableHook to integrate our asynchronous code within Suspense and Error boundary:

In our component, all we should care about is the actual data and its representation:

Finally, we will wrap everything together:

Play with web example at codesandbox.io

Play with native example at snack.expo.io

That is it!

Details

The Suspense and Error Boundaries are like try-catch blocks for components.

  • The Suspense will catch any promise. It will wait until the promise will be fulfilled rendering its children or in case of the promise being rejected it will throw the rejection value.
  • The Error Boundary will catch anything.

Here is what hypothetical code might look like

Therefore you should enclose the Suspense within Error Boundary and not vice versa, as the Error Boundary will catch a promise before the Suspense.

Of course, you can make many layers of nesting of Suspense and Error Boundaries, fine-tuning the desired outcome.

This throw and catch mechanics will only work during React’s rendering phase. So if you will try to throw in some event, it will not work. You can useEventThrow in this case.

Thank you!

--

--