Closed trashhalo closed 3 years ago
Like in actual suspense, on the client-side, suspending is like swapping out the current rendering tree temporarily. That means that if your component instance stops suspending it will re-render, similar to what happens when you call setState
during the initial mount syncronously, for instance. The component will continue rendering and pick up where it's left off. However, that means that the next time it renders you have to ensure it has proper data. It's not possible to continuously keep throwing a promise. To put it in other words, if a component always throws then it has no chance of ever rendering with data, which you can see in the tests: https://github.com/FormidableLabs/react-ssr-prepass/blob/a2660b455f992f43ce73b0fb271bf2df66772dfa/src/__tests__/suspense.test.js#L479-L481
So, if you're just testing this out, make sure that any one component instance throws once, writes to a cache, then resolves and re-renders with a synchronous values. This is basically the "read" pattern, where you either return a value or throw a promise that indicates when a synchronous value on calling read()
is available.
Thank you, Will give it a shot tonight! It might make sense to add a usage example to the readme. Will gladly contribute one if I can get it to work locally.
Heres what I ultimately came up with that passes the test case.
Feels pretty gross. I dont like how the cache lives on over multiple renders. Maybe a context value would do better? I tried to move cache into Async but then it just throws forever. I would imagine some of this would be hidden with hooks/components?
Ive been reading the suspense test cases for a couple hours now and I just cannot get this to work.
I expect when this renders to see
<h1 id="async-h1">hello</h1>
but the thrown promise is bubbling all the way out and failing the build with a thrown object. I am sure I am doing something wrong here.