-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Bug: <Suspense> fallback is rendered inconsistently when there’s a hydration mismatch + the boundary suspends during hydration #28285
Comments
Spent a bunch of time debugging this, and I think I understand what’s causing this. BugLet’s say we’re trying to hydrate the following tree: <Suspense>
<div>
<span />
<span />
[text content] ← this text content causes a hydration mismatch
<span />
<span />
<ComponentThatSuspends />
</div>
</Suspense> Here’s why the bug happens:
What should React do?Just from the code perspective, it feels easier/cheaper to keep the “normal” case – always resetting the But from the UX perspective, I’d maybe prefer React to keep the server HTML until the boundary unsuspends?
IDK, feels like a hard choice to make (good thing it’s not mine I guess ^_^) |
…28299) While investigating #28285 I found a possible bug in handling Suspense and mismatches. As the tests show, if the first sibling in a boundary suspends, and the second has a mismatch, we will NOT show a fallback. If the first sibling is a mismatch, and the second sibling suspends, we WILL show a fallback. [Here's a stackbliz showing the behavior on Canary](https://stackblitz.com/edit/stackblitz-starters-bh3snf?file=src%2Fstyle.css,public%2Findex.html,src%2Findex.tsx). This breakage was introduced by: #26380. Before this PR, we would not show a fallback in either case. That PR makes it so that we don't pre-render siblings of suspended trees, so presumably, whatever detection we had to avoid fallbacks on mismatches, requires knowing there's a mismatch in the tree when we suspend.
@rickhanlonii Sorry for the direct ping – I see you referenced this bug in some other PR; any chance this bug can be set to “Confirmed”? (It still reproduces even in |
…acebook#28299) While investigating facebook#28285 I found a possible bug in handling Suspense and mismatches. As the tests show, if the first sibling in a boundary suspends, and the second has a mismatch, we will NOT show a fallback. If the first sibling is a mismatch, and the second sibling suspends, we WILL show a fallback. [Here's a stackbliz showing the behavior on Canary](https://stackblitz.com/edit/stackblitz-starters-bh3snf?file=src%2Fstyle.css,public%2Findex.html,src%2Findex.tsx). This breakage was introduced by: facebook#26380. Before this PR, we would not show a fallback in either case. That PR makes it so that we don't pre-render siblings of suspended trees, so presumably, whatever detection we had to avoid fallbacks on mismatches, requires knowing there's a mismatch in the tree when we suspend.
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment! |
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you! |
React version: 18.2.0
Steps To Reproduce
Create a tiny app that uses
<Suspense>
+ suspends during hydration + has a hydration mismatch, for example:(Full code in a StackBlitz)
Load the app and observe that the suspense fallback is never mounted
Now, wrap the
<LinkThatSuspends />
element with a<div>
:(StackBlitz)
Load the app and observe that the suspense fallback is now mounted
Code example: fallback not mounted · fallback mounted
The current behavior
The
<Suspense>
fallback is rendered inconsistently – depending on whether the element that suspends is wrapped with a<div>
?!The expected behavior
The
<Suspense>
fallback is rendered either never, or always, no matter if the element that suspends is wrapped with anything.The text was updated successfully, but these errors were encountered: