@@ -210,6 +210,7 @@ import {
210210 TransitionRoot ,
211211 TransitionTracingMarker ,
212212} from './ReactFiberTracingMarkerComponent' ;
213+ import { getViewTransitionClassName } from './ReactFiberViewTransitionComponent' ;
213214import {
214215 commitHookLayoutEffects ,
215216 commitHookLayoutUnmountEffects ,
@@ -303,6 +304,7 @@ export let shouldFireAfterActiveInstanceBlur: boolean = false;
303304// Used during the commit phase to track whether a parent ViewTransition component
304305// might have been affected by any mutations / relayouts below.
305306let viewTransitionContextChanged : boolean = false ;
307+ let inUpdateViewTransition : boolean = false ;
306308let rootViewTransitionAffected : boolean = false ;
307309
308310function isHydratingParent ( current : Fiber , finishedWork : Fiber ) : boolean {
@@ -1937,6 +1939,7 @@ export function commitMutationEffects(
19371939 inProgressRoot = root ;
19381940
19391941 rootViewTransitionAffected = false ;
1942+ inUpdateViewTransition = false ;
19401943
19411944 resetComponentEffectTimers ( ) ;
19421945
@@ -2299,7 +2302,7 @@ function commitMutationEffectsOnFiber(
22992302 recursivelyTraverseMutationEffects ( root , finishedWork , lanes ) ;
23002303 commitReconciliationEffects ( finishedWork , lanes ) ;
23012304 }
2302- if ( viewTransitionMutationContext ) {
2305+ if ( viewTransitionMutationContext && inUpdateViewTransition ) {
23032306 // A Portal doesn't necessarily exist within the context of this subtree.
23042307 // Ideally we would track which React ViewTransition component nests the container
23052308 // but that's costly. Instead, we treat each Portal as if it's a new React root.
@@ -2534,11 +2537,16 @@ function commitMutationEffectsOnFiber(
25342537 }
25352538 }
25362539 const prevMutationContext = pushMutationContext ( ) ;
2537- recursivelyTraverseMutationEffects ( root , finishedWork , lanes ) ;
2538- commitReconciliationEffects ( finishedWork , lanes ) ;
2540+ const prevUpdate = inUpdateViewTransition ;
25392541 const isViewTransitionEligible =
25402542 enableViewTransition &&
25412543 includesOnlyViewTransitionEligibleLanes ( lanes ) ;
2544+ const props = finishedWork . memoizedProps ;
2545+ inUpdateViewTransition =
2546+ isViewTransitionEligible &&
2547+ getViewTransitionClassName ( props . default , props . update ) !== 'none' ;
2548+ recursivelyTraverseMutationEffects ( root , finishedWork , lanes ) ;
2549+ commitReconciliationEffects ( finishedWork , lanes ) ;
25422550 if ( isViewTransitionEligible ) {
25432551 if ( current === null ) {
25442552 // This is a new mount. We should have handled this as part of the
@@ -2551,6 +2559,7 @@ function commitMutationEffectsOnFiber(
25512559 finishedWork . flags |= Update ;
25522560 }
25532561 }
2562+ inUpdateViewTransition = prevUpdate ;
25542563 popMutationContext ( prevMutationContext ) ;
25552564 break ;
25562565 }
@@ -2763,6 +2772,8 @@ function commitAfterMutationEffectsOnFiber(
27632772 // Ideally we would track which React ViewTransition component nests the container
27642773 // but that's costly. Instead, we treat each Portal as if it's a new React root.
27652774 // Therefore any leaked resize of a child could affect the root so the root should animate.
2775+ // We only do this if the Portal is inside a ViewTransition and it is not disabled
2776+ // with update="none". Otherwise the Portal is considered not animating.
27662777 rootViewTransitionAffected = true ;
27672778 }
27682779 viewTransitionContextChanged = prevContextChanged ;
0 commit comments