Question: Hooks + Suspense Interactions. Hooks unstable if suspended.
See original GitHub issueDo you want to request a feature or report a bug? Question about the interaction when using Hooks + Suspense. *I am aware that these are not finalized yet. Please close if this has already been considered.
What is the current behavior? I tweeted about this:
- https://twitter.com/tazsingh/status/1083314900586373120
- https://twitter.com/tazsingh/status/1083329402308562944
In essence, Hooks require a full execution of a Component function to register. However, Suspense interrupts that execution such that Hooks aren’t able to effectively register. As such, it’s impossible to rely on the output of any Hooks until all suspended calls are resolved.
Since the vision for Suspense is to use them as the primary async mechanism in React and since Hooks are meant to be composable items within a Component, where it isn’t strictly important to be aware of what is contained in a Hook for it to be useful, I can see this as problematic if they cannot register properly because some other Hook has suspended.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn’t have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
Please feel free to uncomment the section in this CodeSandbox to observe the behaviour I’m noticing. I also describe a related behaviour in my second tweet regarding usage of useMemo
.
https://codesandbox.io/s/9y64nmkrzy
What is the expected behavior? Frankly, I am unsure of the expected behaviour as I believe both of these features to be working as intended hence why I titled this issue as a “question”. I am aware that I am using these features before they are released and proper communication of the usage between Hooks + Suspense is not yet available.
If this is the intended behaviour, cool 👍 If not, I am happy to file a bug report accordingly.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? 16.8.0-alpha.0
Thanks! 🙏
Issue Analytics
- State:
- Created 5 years ago
- Reactions:2
- Comments:5 (3 by maintainers)
Yeah, when a component Suspends, we don’t preserve any of its intermediate state (on either mount or update). We throw it out, and try again once the promise resolves. As Dan mentions, we have some planned optimizations that will allow us to reuse partially completed work (“resuming”), but even then, we would only memoize partial work at the component level, not at the Hook level. (Theoretically we could make it work with Hooks but that’s not in our current plans.) Still, this would only be an optimization. It’s not something you would be able to rely on. There’s a section in this RFC that discusses our rationale a bit: https://github.com/acdlite/rfcs/blob/context-write/text/0000-context-write.md#caching-external-data
One option is to cache the result of
componentExpensive
in an external cache. You could even offload it to a worker and suspend. The benefit of this approach is the computation can be reused across multiple components.I’m on mobile now but let’s see if this clarifies things. Note I might be wrong so check this against your observations.
If component suspends during mount, I think we don’t preserve its state on retry. We attempt to mount from scratch again instead. So it’s expected memo or state aren’t preserved. Suspense is intended to be used with caches outside a component rather than backed by local state. (useMemo is a fair point that isn’t addressed by that though.)
If I’m correct, in the future we plan to implement “resuming” which is an optimization and should allow to reuse results from suspended mount on next attempt. I think maybe this could help the useMemo issue. But I don’t think it would provide strong guarantees either.
I’ll ask @acdlite if this writeup is correct.