Geek With Opinions

React Suspense

January 25, 2019

Well, I did it again… I signed up to talk about a topic so now I need to learn about it. Story of my life. So it all started in October of 2018. I was lucky enough to be able to attend ReactConf. Yup, the one where the React team announced hooks and suspense. When I returned from React Conf, I decided to share the knowledge that I gain from React Conf and since React conf with my coworker and probably others. What follows is some notes and links on Suspense. I am not going to regurgitate much from any of the links

First stop, if you haven’t watch the video from React Conf for Suspense, you should start there. To get the most from the video, it is probably a good idea to start with the talks on Hooks then go into the ones on suspense.

In my search of information on how to suspense and concurrent mode, I found this GitHub repo where the maintainer is keeping up with info on APIs and how to use. At the moment of writing this, all these APIs are in flux documentation is slim at best. This repo has been helpful.

So you may have noticed that During Jared Palmer’s talk, he announced The Platform module. Well, if you are like me, you may be wondering what magic it is doing to work. Well, it is using React-Cache to do its dirty work. So I would say it is not production ready at the point of writing this.

At this point, you maybe wondering how does this all actually work. Abstractions and black boxes are great but sometimes you want to know a bit about how they work. Well wonder no more. React Suspense with the FetchAPI does a good job explaining how it works.

The secret to suspense? Are you ready? The magic is just a simple promise. If you want to DIY suspense, the thing react-cache uses, just throw a promise. As you can see here in react-cache: https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js#L159.

At a super high level, works just like an error boundary component. The promise is thrown, the suspense component catches it and waits for the promise to resolve. While waiting for the promise to resolve, it renders the fallback component. Once the promise resolves, it will switch from rendering the fallback component to the real children.

Now you may be asking, but wont the child component just re-throw the promise again? And the answer to that is no. Ever library that is suspense enabled that I have seen so far has the smarts to know if a promise has resolved. In react-cache’s case, instead of throwing the promise, it returns the value of the promise. This is how it can look like synchronous code but still be asynchronous.

Lastly, there is one gotcha. I don’t know why but it is possible for the child component to attempt to be rendered again before the thrown promise is resolved. In this case, the same promise must be re-thrown. If you don’t do this, the child component(s) will be attemp to render.


Tony Gemoll

Written by Tony Gemoll. Shorter opinions found on twitter