Asynchronous rendering with React
How the new React Suspense API might reshape the way we build components
A more accessible, readable, mobile-friendly and up to date version of this story is available on my personal blog!
Since I’ve started playing with React a couple of years ago, I’ve always been a big fan of functional components. Their simplicity and conciseness make them easy to read and test. The problem though was that, until now, there was no way to do asynchronous calls which is the crucial part of most applications in the real world, so classes were always the way to go.
However, starting from React 16.6.0 and the new Suspense API, this is not an issue anymore, functional components can now perform asynchronous calls and render data that comes from them. In this post, I’m going to show you an up to date example so you can easily test the Suspense API.
Note: Although it’s available through the last official version of React, using Suspense as I’ll show you in this post is not yet intended for production. This example solely exists as an experiment.
What is Suspense in a nutshell?
Suspense basically suspends the rendering of a component while loading data from a cache. This means that our component will only show up once the whole tree is ready. If the data we’re trying to render is not in the cache, the cache throws a Promise. When the promise resolves, the rendering continues.
While all of this is happening, Suspense will render a fallback component which could be for example a loading indicator, a message, or anything we usually render in our applications to signal the user that something asynchronous is happening.
A new way to build components
As of today, when we want to render a component that shows some data coming from an asynchronous call in React, we’re stuck with classes. We have to use the component lifecycle methods to ensure the call happens on mount, and use the local state to manage the loading state. We can see below a small example of a pattern that I’m sure pretty much every React developer had to follow:
How Suspense changes that? Well, quite a lot actually if you compare the code above with the following one:
As we can see with this example: no more class! Suspense is managing for us the loading state through the
fallback prop, which is rendered until
List is ready to be rendered, that is when the dependent asynchronous call resolves and returns the data. However, this is only a partial example. As stated in the first part, the rendering of
List in this example is suspended while loading data from a cache, which is what the
Fetcher function is all about.
This is key for getting the example above to work. The caching part is needed for Suspense to read the data from the asynchronous call.
Before diving in the details, let’s look at how the
Fetcher function is implemented for our example:
For this post I used react-cache. It’s a package made by the React core team that provides a basic cache that is going to store asynchronous data, like the data that we’re getting once our fetch call resolves, and allows us to access that data asynchronously. In the code snippet above we basically use the
unstable_createResource function where we pass our asynchronous call, which will initiate a cache and store the resulting data into it. Accessing that data from the cache is done through the
read function as we can see in the Code Snippet 2. However, this way of doing caching is currently not meant to be used in production (the React team emphasized this quite a bit in the README of this repository).
Here’s the full example for this article:
I made this example available in a Github repository based on
create-react-app so you can also give it a try and experiment with Suspense very quickly!
I really can’t wait for this pattern to be ready for production. Combining Suspense and the recently announced React hooks is getting us closer to building React apps fully based on functional components. If you want to learn more about Suspense here’s a really complete summary in a tweet from a member of the React team:
If you liked this article don’t forget to hit the “clap” button and if you have any other questions I’m always reachable on Twitter, or on my website. You can also subscribe to my Medium publication to not miss my next post.
What to read next?
If you want to read more about React or frontend development, you can check the following articles:
Making flexible, easily testable and reusable views in React without ending in “markup hell”
Using Flow generics to type generic React components
How Flow generics help typing complex multi-purpose components
Have a wonderful day.