Claim the useId name space for every auto named ViewTransition (#33200)

This is a partial revert of #33094. It's true that we don't need the
server and client ViewTransition names to line up. However the server
does need to be able to generate deterministic names for itself. The
cheapest way to do that is using the useId algorithm. When it's used by
the server, the client needs to also materialize an ID even if it
doesn't use it.
This commit is contained in:
Sebastian Markbåge 2025-05-14 17:52:41 -04:00 committed by GitHub
parent 63d664b220
commit 96eb84e493
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 1 deletions

View File

@ -3543,6 +3543,12 @@ function updateViewTransition(
current === null
? ViewTransitionNamedMount | ViewTransitionNamedStatic
: ViewTransitionNamedStatic;
} else {
// The server may have used useId to auto-assign a generated name for this boundary.
// We push a materialization to ensure child ids line up with the server.
if (getIsHydrating()) {
pushMaterializedTreeId(workInProgress);
}
}
if (__DEV__) {
// $FlowFixMe[prop-missing]

View File

@ -2273,7 +2273,23 @@ function renderViewTransition(
) {
const prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, props.children, -1);
if (props.name != null && props.name !== 'auto') {
renderNodeDestructive(request, task, props.children, -1);
} else {
// This will be auto-assigned a name which claims a "useId" slot.
// This component materialized an id. We treat this as its own level, with
// a single "child" slot.
const prevTreeContext = task.treeContext;
const totalChildren = 1;
const index = 0;
// Modify the id context. Because we'll need to reset this if something
// suspends or errors, we'll use the non-destructive render path.
task.treeContext = pushTreeContext(prevTreeContext, totalChildren, index);
renderNode(request, task, props.children, -1);
// Like the other contexts, this does not need to be in a finally block
// because renderNode takes care of unwinding the stack.
task.treeContext = prevTreeContext;
}
task.keyPath = prevKeyPath;
}