@@ -152,14 +152,6 @@ if (__DEV__) {
152152 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set ( ) ;
153153}
154154
155- // Used during the commit phase to track the state of the Offscreen component stack.
156- // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor.
157- // Only used when enableSuspenseLayoutEffectSemantics is enabled.
158- let offscreenSubtreeIsHidden : boolean = false ;
159- const offscreenSubtreeIsHiddenStack : Array < boolean > = [];
160- let offscreenSubtreeWasHidden: boolean = false;
161- const offscreenSubtreeWasHiddenStack: Array< boolean > = [];
162-
163155const PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set ;
164156
165157let nextEffect : Fiber | null = null ;
@@ -2283,13 +2275,15 @@ export function commitLayoutEffects(
22832275 committedLanes : Lanes ,
22842276) : void {
22852277 nextEffect = finishedWork ;
2286- commitLayoutEffects_begin ( finishedWork , root , committedLanes ) ;
2278+ commitLayoutEffects_begin ( finishedWork , root , committedLanes , false , false ) ;
22872279}
22882280
22892281function commitLayoutEffects_begin (
22902282 subtreeRoot : Fiber ,
22912283 root : FiberRoot ,
22922284 committedLanes : Lanes ,
2285+ subtreeWasHidden : boolean ,
2286+ subtreeIsHidden : boolean ,
22932287) {
22942288 // Suspense layout effects semantics don't change for legacy roots.
22952289 const isModernRoot = ( subtreeRoot . mode & ConcurrentMode ) !== NoMode ;
@@ -2305,11 +2299,24 @@ function commitLayoutEffects_begin(
23052299 const wasHidden = current !== null && current . memoizedState !== null ;
23062300 const isHidden = fiber . memoizedState !== null ;
23072301
2308- offscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden ;
2309- offscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden ;
2302+ const newOffscreenSubtreeWasHidden = wasHidden || subtreeWasHidden ;
2303+ const newOffscreenSubtreeIsHidden = isHidden || subtreeIsHidden ;
23102304
2311- offscreenSubtreeWasHiddenStack . push ( wasHidden ) ;
2312- offscreenSubtreeIsHiddenStack . push ( isHidden ) ;
2305+ if (
2306+ newOffscreenSubtreeWasHidden !== subtreeWasHidden ||
2307+ newOffscreenSubtreeIsHidden !== subtreeIsHidden
2308+ ) {
2309+ // Traverse the Offscreen subtree with the current Offscreen as the root.
2310+ commitLayoutEffects_begin (
2311+ fiber , // New root; bubble back up to here and stop.
2312+ root ,
2313+ committedLanes ,
2314+ newOffscreenSubtreeWasHidden ,
2315+ newOffscreenSubtreeIsHidden ,
2316+ ) ;
2317+ nextEffect = fiber . sibling ;
2318+ continue ;
2319+ }
23132320 }
23142321 }
23152322
@@ -2318,8 +2325,7 @@ function commitLayoutEffects_begin(
23182325 nextEffect = firstChild ;
23192326 } else {
23202327 if ( enableSuspenseLayoutEffectSemantics && isModernRoot ) {
2321- const visibilityChanged =
2322- ! offscreenSubtreeIsHidden && offscreenSubtreeWasHidden ;
2328+ const visibilityChanged = ! subtreeIsHidden && subtreeWasHidden ;
23232329 if (
23242330 visibilityChanged &&
23252331 ( fiber . subtreeFlags & LayoutStatic ) !== NoFlags &&
@@ -2334,7 +2340,13 @@ function commitLayoutEffects_begin(
23342340 }
23352341 }
23362342
2337- commitLayoutMountEffects_complete ( subtreeRoot , root , committedLanes ) ;
2343+ commitLayoutMountEffects_complete (
2344+ subtreeRoot ,
2345+ root ,
2346+ committedLanes ,
2347+ subtreeWasHidden ,
2348+ subtreeIsHidden ,
2349+ ) ;
23382350 }
23392351 }
23402352}
@@ -2343,35 +2355,20 @@ function commitLayoutMountEffects_complete(
23432355 subtreeRoot : Fiber ,
23442356 root : FiberRoot ,
23452357 committedLanes : Lanes ,
2358+ subtreeWasHidden : boolean ,
2359+ subtreeIsHidden : boolean ,
23462360) {
23472361 // Suspense layout effects semantics don't change for legacy roots.
23482362 const isModernRoot = ( subtreeRoot . mode & ConcurrentMode ) !== NoMode ;
23492363
23502364 while ( nextEffect !== null ) {
23512365 const fiber = nextEffect ;
23522366
2353- if ( enableSuspenseLayoutEffectSemantics && isModernRoot ) {
2354- if ( fiber . tag === OffscreenComponent ) {
2355- offscreenSubtreeWasHiddenStack . pop ( ) ;
2356- offscreenSubtreeIsHiddenStack . pop ( ) ;
2357- offscreenSubtreeWasHidden =
2358- offscreenSubtreeWasHiddenStack . length > 0 &&
2359- offscreenSubtreeWasHiddenStack [
2360- offscreenSubtreeWasHiddenStack . length - 1
2361- ] ;
2362- offscreenSubtreeIsHidden =
2363- offscreenSubtreeIsHiddenStack . length > 0 &&
2364- offscreenSubtreeIsHiddenStack [
2365- offscreenSubtreeIsHiddenStack . length - 1
2366- ] ;
2367- }
2368- }
2369-
23702367 if (
23712368 enableSuspenseLayoutEffectSemantics &&
23722369 isModernRoot &&
2373- offscreenSubtreeWasHidden &&
2374- ! offscreenSubtreeIsHidden
2370+ subtreeWasHidden &&
2371+ ! subtreeIsHidden
23752372 ) {
23762373 // Inside of an Offscreen subtree that changed visibility during this commit.
23772374 // If this subtree was hidden, layout effects will have already been destroyed (during mutation phase)
0 commit comments