It's the hottest topic these days in the React community, and everybody gets either super excited or completely confused when the word "Suspense" i...
For further actions, you may consider blocking this person and/or reporting abuse
Nice article!, one question though, wouldn't it be simpler and maybe more performant if you just passed the promise instead of a method returning a promise? per example:
No need for caching the request because it's already executed and doesn't need to be executed inside the function.
Calling
fetch
immediately will start the api call immediately. But data needs to be retrieved on demand, and usually with parameters (fetch a user by its id). You cannot create fetch promises for all possible IDs you don't know you're going to use.Also, we're not caching the fetch requests (i.e. the functions that return the promises), but the generated data reader functions (i.e. the functions that just return the data, or throw the in-progress promises).
Thanks for writing this post up last year - I'm really enjoying playing around with the library!
I'm trying to wrap my head around Suspense and the thing I can't figure out right now, though, is why you have the pattern of calling your hook outside of the Suspense barrier and then passing the throwing reader function into the child component inside the barrier. This seems more difficult to reason about than the pattern in
reactfire
where the hook call itself can throw a promise. Is there something I'm missing here about Suspense or is this just a convention difference?Ok, I think I figured it out.
The issue is that you need some way to persist the state that is in flight to some point outside of the Suspense boundary. Because the Suspense-aware API requires throwing a value, it interrupts the execution of the component(s) underneath the nearest Suspense component, meaning that any values in their state (including their hooks' states) are wiped out.
reactfire
gets away with its design pattern because it has the context provider higher up in the component tree where it can hang the loads in progress.Hi Andrei, nice article! I'm new to react and I just have some questions. You use this in production which means you are using the react concurrent mode, right?
Did you come across any compatibility or any other issues in production? Does your package use-async-resource need react concurrent mode? Can I use your use the package for my project safely?
Hi Siddiq. As explained in the article, the
use-async-resource
package is working with current versions of React, without concurrent mode.Out of interest do you still use redux observable and do you foresee use cases for it alongside suspense? I.e. for a new project do you think you'd end up bringing redux observable into the mix? Thanks for the article!
In theory, you could hook up your redux (and redux observables) setup with Suspense. In practice, however, I think Suspense lets you move away from that.
Redux (and especially redux observables) requires a lot of under-the-hood boilerplate, and all data flows are created outside your JSX. With Suspense, you can control the flow of data directly from JSX, and handling loading and error states becomes so much simpler. And if you need to use and manage pieces of data in multiple places, a simple context provider can do the job.
This is a fantastic post! Very well written!
(I just joined dev.to only to be able to follow you!)
You think you'll be maintaining the git repo and npm package going forward?
Thank you! I'm glad you enjoyed the read. :D
Yes, I'll do my best to keep it up to date!
Beautifully explained and detailed. Thank you.