-
Notifications
You must be signed in to change notification settings - Fork 45.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested <Suspense>
boundaries do not work with useTransition
#24759
Comments
This behavior is intentional.
This is how it worked in very early prototypes but we've changed the behavior. In the stable release, it only "waits" for "existing" boundaries — but it won't wait for the "new" ones. In other words, wrapping a piece of content that delays a transition into Suspense lets you decouple it from the transition, and let it finish later. |
Thanks for the quick reply. Are they maybe any plans to make this behaviour more flexible? I'm working on a system with dashboard pages. The dashboard page itself uses suspense to load the page state/what widgets are configured etc. And then as a second level there are widgets which each have suspense wrappers. It would be great if I could use startTransition to switch to a different dashboard with the widgets displaying data, but with the current solution the page switch just takes me to a page with loading spinners on each of the widgets. |
What we've seen with the old behavior in practice is that a single mistake (adding a slow data source somewhere on the page) causes regressions to many interactions (all transitions to that page) without a clear way to fix it. Whereas with the current behavior, you have control: if you don't want to wait for something, you wrap it in Suspense. I would suggest to think about two questions:
If neither of these approaches work well for you, can you share why? |
That's an interesting point about performance. I guess at the moment I've been primarily been focusing on the transition effect and assuming that if performance was really bad the transition would timeout. (Luckily at the moment our apis are nice and fast, but as you say it only takes one). Re your questions:
I guess in an ideal world I'm imagining being able to mark specific suspense boundaries as 'ignore when transitioning' and also, re performance, perhaps customize the transition timeout time if React's default time feels a bit slow. Overall though, transitions are better than what we've had before, so I can't complain. |
We've removed the concept of "timeouts" because there was no good way to pick one (three seconds? five seconds? ten seconds?) and the overall UI effect felt very non-determinisic (a sudden jump to a spinner.. but unclear why since the user didn't do anything different). So now it's either "everything reveals asap*" (for new boundaries) or "everything stays pending". (* — not actually asap because we throttle "revealing the next level of fallbacks" every 500ms to avoid flashes of different levels of spinners)
You can design an intentional glimmer that approximates all the widgets together but is not actually a bunch of spinners. I think overall that's preferred to spinners anyway, and many UIs are moving to that style these days. Eg Vercel dashboard:
It wouldn't if you wrap "adding a widget" into a transition. |
Ah that is all very interesting. Clearly my understanding of suspense/transitions is outdated - I didn't realise there are no timeouts anymore. That does make a big difference as to what I'm thinking of loading behind transitions. Your explanation about non-determinism does make sense though. I think I need to play around with a simulated slow user experience for a tab switch to see if removing widget boundaries is a good idea.
Cunning! Yes we should move to glimmers to have the best experience. We actually use delay/fade spinners so it doesn't look quite as busy (assuming performance is good). And your comment earlier about the upcoming SuspenseList should definitely help with the overall transition as widgets are ready. Thanks for your detailed replies. |
No prob! In general, our conclusion was that for navigations you want to get to the "skeleton" of the next page as soon as possible (to communicate the navigation is happening), but for "refreshing" the existing content, you want to use a transition. And then where you place the Suspense boundaries lets you adjust the behavior. |
React version: 18
Steps To Reproduce
<Suspense>
boundariesuseTransition
Link to code example: https://codesandbox.io/s/inspiring-wind-1bedy7
The current behavior
useTransition waits for the first Suspense boundary to be ready and then reveals showing the nested Suspense boundary still in its fallback state.
The expected behavior
useTransition should wait for the entire tree to be ready before revealing
Thanks React team for the great work by the way!
The text was updated successfully, but these errors were encountered: