@@ -280,6 +280,7 @@ import {
280280 createCapturedValueFromError ,
281281 createCapturedValueAtFiber ,
282282} from './ReactCapturedValue' ;
283+ import { OffscreenVisible } from './ReactFiberOffscreenComponent' ;
283284import {
284285 createClassErrorUpdate ,
285286 initializeClassErrorUpdate ,
@@ -620,6 +621,18 @@ function updateOffscreenComponent(
620621 const prevState : OffscreenState | null =
621622 current !== null ? current . memoizedState : null ;
622623
624+ if ( current === null && workInProgress . stateNode === null ) {
625+ // We previously reset the work-in-progress.
626+ // We need to create a new Offscreen instance.
627+ const primaryChildInstance : OffscreenInstance = {
628+ _visibility : OffscreenVisible ,
629+ _pendingMarkers : null ,
630+ _retryCache : null ,
631+ _transitions : null ,
632+ } ;
633+ workInProgress . stateNode = primaryChildInstance ;
634+ }
635+
623636 if (
624637 nextProps . mode === 'hidden' ||
625638 ( enableLegacyHidden && nextProps . mode === 'unstable-defer-without-hiding' )
@@ -788,6 +801,26 @@ function updateOffscreenComponent(
788801 return workInProgress . child ;
789802}
790803
804+ function bailoutOffscreenComponent (
805+ current : Fiber | null ,
806+ workInProgress : Fiber ,
807+ ) : Fiber | null {
808+ if (
809+ ( current === null || current . tag !== OffscreenComponent ) &&
810+ workInProgress . stateNode === null
811+ ) {
812+ const primaryChildInstance : OffscreenInstance = {
813+ _visibility : OffscreenVisible ,
814+ _pendingMarkers : null ,
815+ _retryCache : null ,
816+ _transitions : null ,
817+ } ;
818+ workInProgress . stateNode = primaryChildInstance ;
819+ }
820+
821+ return workInProgress . sibling ;
822+ }
823+
791824function deferHiddenOffscreenComponent (
792825 current : Fiber | null ,
793826 workInProgress : Fiber ,
@@ -1095,9 +1128,13 @@ function updateActivityComponent(
10951128 if ( nextProps . mode === 'hidden' ) {
10961129 // SSR doesn't render hidden Activity so it shouldn't hydrate,
10971130 // even at offscreen lane. Defer to a client rendered offscreen lane.
1098- mountActivityChildren ( workInProgress , nextProps , renderLanes ) ;
1131+ const primaryChildFragment = mountActivityChildren (
1132+ workInProgress ,
1133+ nextProps ,
1134+ renderLanes ,
1135+ ) ;
10991136 workInProgress . lanes = laneToLanes ( OffscreenLane ) ;
1100- return null ;
1137+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
11011138 } else {
11021139 // We must push the suspense handler context *before* attempting to
11031140 // hydrate, to avoid a mismatch in case it errors.
@@ -2373,7 +2410,7 @@ function updateSuspenseComponent(
23732410 if ( showFallback ) {
23742411 pushFallbackTreeSuspenseHandler ( workInProgress ) ;
23752412
2376- const fallbackFragment = mountSuspenseFallbackChildren (
2413+ mountSuspenseFallbackChildren (
23772414 workInProgress ,
23782415 nextPrimaryChildren ,
23792416 nextFallbackChildren ,
@@ -2408,7 +2445,7 @@ function updateSuspenseComponent(
24082445 }
24092446 }
24102447
2411- return fallbackFragment ;
2448+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
24122449 } else if (
24132450 enableCPUSuspense &&
24142451 typeof nextProps . unstable_expectedLoadTime === 'number'
@@ -2417,7 +2454,7 @@ function updateSuspenseComponent(
24172454 // unblock the surrounding content. Then immediately retry after the
24182455 // initial commit.
24192456 pushFallbackTreeSuspenseHandler ( workInProgress ) ;
2420- const fallbackFragment = mountSuspenseFallbackChildren (
2457+ mountSuspenseFallbackChildren (
24212458 workInProgress ,
24222459 nextPrimaryChildren ,
24232460 nextFallbackChildren ,
@@ -2444,7 +2481,7 @@ function updateSuspenseComponent(
24442481 // RetryLane even if it's the one currently rendering since we're leaving
24452482 // it behind on this node.
24462483 workInProgress . lanes = SomeRetryLane ;
2447- return fallbackFragment ;
2484+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
24482485 } else {
24492486 pushPrimaryTreeSuspenseHandler ( workInProgress ) ;
24502487 return mountSuspensePrimaryChildren (
@@ -2479,7 +2516,7 @@ function updateSuspenseComponent(
24792516
24802517 const nextFallbackChildren = nextProps . fallback ;
24812518 const nextPrimaryChildren = nextProps . children ;
2482- const fallbackChildFragment = updateSuspenseFallbackChildren (
2519+ updateSuspenseFallbackChildren (
24832520 current ,
24842521 workInProgress ,
24852522 nextPrimaryChildren ,
@@ -2532,7 +2569,7 @@ function updateSuspenseComponent(
25322569 renderLanes ,
25332570 ) ;
25342571 workInProgress . memoizedState = SUSPENDED_MARKER ;
2535- return fallbackChildFragment ;
2572+ return bailoutOffscreenComponent ( current . child , primaryChildFragment ) ;
25362573 } else {
25372574 if (
25382575 prevState !== null &&
@@ -2788,7 +2825,7 @@ function updateSuspenseFallbackChildren(
27882825 primaryChildFragment . sibling = fallbackChildFragment ;
27892826 workInProgress . child = primaryChildFragment ;
27902827
2791- return fallbackChildFragment ;
2828+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
27922829}
27932830
27942831function retrySuspenseComponentWithoutHydrating (
@@ -3094,14 +3131,13 @@ function updateDehydratedSuspenseComponent(
30943131
30953132 const nextPrimaryChildren = nextProps . children ;
30963133 const nextFallbackChildren = nextProps . fallback ;
3097- const fallbackChildFragment =
3098- mountSuspenseFallbackAfterRetryWithoutHydrating (
3099- current ,
3100- workInProgress ,
3101- nextPrimaryChildren ,
3102- nextFallbackChildren ,
3103- renderLanes ,
3104- ) ;
3134+ mountSuspenseFallbackAfterRetryWithoutHydrating (
3135+ current ,
3136+ workInProgress ,
3137+ nextPrimaryChildren ,
3138+ nextFallbackChildren ,
3139+ renderLanes ,
3140+ ) ;
31053141 const primaryChildFragment : Fiber = ( workInProgress . child : any ) ;
31063142 primaryChildFragment . memoizedState =
31073143 mountSuspenseOffscreenState ( renderLanes ) ;
@@ -3111,7 +3147,7 @@ function updateDehydratedSuspenseComponent(
31113147 renderLanes ,
31123148 ) ;
31133149 workInProgress . memoizedState = SUSPENDED_MARKER ;
3114- return fallbackChildFragment ;
3150+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
31153151 }
31163152 }
31173153}
0 commit comments