-
Notifications
You must be signed in to change notification settings - Fork 45.7k
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
Add tail="hidden" option to SuspenseList #16024
Conversation
ReactDOM: size: 0.0%, gzip: -0.0% Details of bundled changes.Comparing: 29b4559...6ec55cb react-art
react-dom
react-native-renderer
react-test-renderer
react-reconciler
Generated by 🚫 dangerJS |
SSR is pretty tricky with this approach, since we won't have DOM nodes for all the items in the list during reconciliation. If we assume that we have the same number of items in the list and that we suspend at at least the same places as the server, then at least the collapsed mode works out. Because we'll at most render the last tail item which will be in fallback state on the server and get replaced on the client. However, with "hidden" mode, we don't know that we've hit the end of the list yet. We need to render it first and when we try to do that, we get a hydration error because that node was deleted. If they were actually just hidden we could potentially start hydrating them. |
4c8d987
to
8039935
Compare
d52bc4b
to
8654058
Compare
This lets us reuse the found fallback so we can transfer the update queue from it.
8654058
to
de7e82b
Compare
This function exists to optimize the case where all the boundaries in the head are already suspended. In that case there's no need to do a second rerender pass. However, in that case, we're not really going to show much new content on the screen anyway. So I'm not sure it's worth keeping this special case around. scan every row
de7e82b
to
6ec55cb
Compare
I think this is ready for review and landing now. I ended up needing to do a lot of factoring to make it nicer and found a number of bugs along the way. Particularly, to minimize file size I ended up removing one optimization which causes extra rerenders. 6ec55cb I'm not sure this is the right call but maybe with resuming this won't matter much. I'll address the SSR case in a follow up. |
hasSuspendedChildrenAndNewContent(workInProgress, renderedTail); | ||
let newThennables = suspended.updateQueue; | ||
if (newThennables !== null) { | ||
workInProgress.updateQueue = newThennables; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this approach something we'll want to rethink later? By always attaching thenables to the SuspenseList instead of the inner boundary, perhaps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could possibly do that in throwException, yea.
Builds on top of #16007.
This is similar to
tail="collapsed"
except it hides all rows in the tail. The added complexity here is that sometimes we only know that we've hit the tail after we've already rendered this row. So we need undo the effects added by rendering the row.Additionally, by not committing the boundary, there's nothing to retry. So we need to transfer the promise set to the list so that we get a retry if the only thing to ping was in the tail.