@@ -278,10 +278,7 @@ import {
278278 createCapturedValueFromError ,
279279 createCapturedValueAtFiber ,
280280} from './ReactCapturedValue' ;
281- import {
282- OffscreenHidden ,
283- OffscreenVisible ,
284- } from './ReactFiberOffscreenComponent' ;
281+ import { OffscreenVisible } from './ReactFiberOffscreenComponent' ;
285282import {
286283 createClassErrorUpdate ,
287284 initializeClassErrorUpdate ,
@@ -622,21 +619,22 @@ function updateOffscreenComponent(
622619 const prevState : OffscreenState | null =
623620 current !== null ? current . memoizedState : null ;
624621
625- const nextHidden =
626- nextProps . mode === 'hidden' ||
627- ( enableLegacyHidden && nextProps . mode === 'unstable-defer-without-hiding' ) ;
628-
629622 if ( current === null && workInProgress . stateNode === null ) {
630- const primaryChildInstance = {
631- _visibility : nextHidden ? OffscreenHidden : OffscreenVisible ,
623+ // We previously reset the work-in-progress.
624+ // We need to create a new Offscreen instance.
625+ const primaryChildInstance : OffscreenInstance = {
626+ _visibility : OffscreenVisible ,
632627 _pendingMarkers : null ,
633628 _retryCache : null ,
634629 _transitions : null ,
635630 } ;
636631 workInProgress . stateNode = primaryChildInstance ;
637632 }
638633
639- if ( nextHidden ) {
634+ if (
635+ nextProps . mode === 'hidden' ||
636+ ( enableLegacyHidden && nextProps . mode === 'unstable-defer-without-hiding' )
637+ ) {
640638 // Rendering a hidden tree.
641639
642640 const didSuspend = ( workInProgress . flags & DidCapture ) !== NoFlags ;
@@ -801,6 +799,26 @@ function updateOffscreenComponent(
801799 return workInProgress . child ;
802800}
803801
802+ function bailoutOffscreenComponent (
803+ current : Fiber | null ,
804+ workInProgress : Fiber ,
805+ ) : Fiber | null {
806+ if (
807+ ( current === null || current . tag !== OffscreenComponent ) &&
808+ workInProgress . stateNode === null
809+ ) {
810+ const primaryChildInstance : OffscreenInstance = {
811+ _visibility : OffscreenVisible ,
812+ _pendingMarkers : null ,
813+ _retryCache : null ,
814+ _transitions : null ,
815+ } ;
816+ workInProgress . stateNode = primaryChildInstance ;
817+ }
818+
819+ return workInProgress . sibling ;
820+ }
821+
804822function deferHiddenOffscreenComponent (
805823 current : Fiber | null ,
806824 workInProgress : Fiber ,
@@ -1101,9 +1119,13 @@ function updateActivityComponent(
11011119 if ( nextProps . mode === 'hidden' ) {
11021120 // SSR doesn't render hidden Activity so it shouldn't hydrate,
11031121 // even at offscreen lane. Defer to a client rendered offscreen lane.
1104- mountActivityChildren ( workInProgress , nextProps , renderLanes ) ;
1122+ const primaryChildFragment = mountActivityChildren (
1123+ workInProgress ,
1124+ nextProps ,
1125+ renderLanes ,
1126+ ) ;
11051127 workInProgress . lanes = laneToLanes ( OffscreenLane ) ;
1106- return null ;
1128+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
11071129 } else {
11081130 // We must push the suspense handler context *before* attempting to
11091131 // hydrate, to avoid a mismatch in case it errors.
@@ -2369,7 +2391,7 @@ function updateSuspenseComponent(
23692391 if ( showFallback ) {
23702392 pushFallbackTreeSuspenseHandler ( workInProgress ) ;
23712393
2372- const fallbackFragment = mountSuspenseFallbackChildren (
2394+ mountSuspenseFallbackChildren (
23732395 workInProgress ,
23742396 nextPrimaryChildren ,
23752397 nextFallbackChildren ,
@@ -2378,13 +2400,6 @@ function updateSuspenseComponent(
23782400 const primaryChildFragment : Fiber = ( workInProgress . child : any ) ;
23792401 primaryChildFragment . memoizedState =
23802402 mountSuspenseOffscreenState ( renderLanes ) ;
2381- const primaryChildInstance = {
2382- _visibility : OffscreenHidden ,
2383- _pendingMarkers : null ,
2384- _retryCache : null ,
2385- _transitions : null ,
2386- } ;
2387- primaryChildFragment . stateNode = primaryChildInstance ;
23882403 primaryChildFragment . childLanes = getRemainingWorkInPrimaryTree (
23892404 current ,
23902405 didPrimaryChildrenDefer ,
@@ -2411,7 +2426,7 @@ function updateSuspenseComponent(
24112426 }
24122427 }
24132428
2414- return fallbackFragment ;
2429+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
24152430 } else if (
24162431 enableCPUSuspense &&
24172432 typeof nextProps . unstable_expectedLoadTime === 'number'
@@ -2420,7 +2435,7 @@ function updateSuspenseComponent(
24202435 // unblock the surrounding content. Then immediately retry after the
24212436 // initial commit.
24222437 pushFallbackTreeSuspenseHandler ( workInProgress ) ;
2423- const fallbackFragment = mountSuspenseFallbackChildren (
2438+ mountSuspenseFallbackChildren (
24242439 workInProgress ,
24252440 nextPrimaryChildren ,
24262441 nextFallbackChildren ,
@@ -2447,7 +2462,7 @@ function updateSuspenseComponent(
24472462 // RetryLane even if it's the one currently rendering since we're leaving
24482463 // it behind on this node.
24492464 workInProgress . lanes = SomeRetryLane ;
2450- return fallbackFragment ;
2465+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
24512466 } else {
24522467 pushPrimaryTreeSuspenseHandler ( workInProgress ) ;
24532468 return mountSuspensePrimaryChildren (
@@ -2482,7 +2497,7 @@ function updateSuspenseComponent(
24822497
24832498 const nextFallbackChildren = nextProps . fallback ;
24842499 const nextPrimaryChildren = nextProps . children ;
2485- const fallbackChildFragment = updateSuspenseFallbackChildren (
2500+ updateSuspenseFallbackChildren (
24862501 current ,
24872502 workInProgress ,
24882503 nextPrimaryChildren ,
@@ -2535,7 +2550,7 @@ function updateSuspenseComponent(
25352550 renderLanes ,
25362551 ) ;
25372552 workInProgress . memoizedState = SUSPENDED_MARKER ;
2538- return fallbackChildFragment ;
2553+ return bailoutOffscreenComponent ( current . child , primaryChildFragment ) ;
25392554 } else {
25402555 pushPrimaryTreeSuspenseHandler ( workInProgress ) ;
25412556
@@ -2780,7 +2795,7 @@ function updateSuspenseFallbackChildren(
27802795 primaryChildFragment . sibling = fallbackChildFragment ;
27812796 workInProgress . child = primaryChildFragment ;
27822797
2783- return fallbackChildFragment ;
2798+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
27842799}
27852800
27862801function retrySuspenseComponentWithoutHydrating (
@@ -2820,7 +2835,7 @@ function mountSuspenseFallbackAfterRetryWithoutHydrating(
28202835) {
28212836 const fiberMode = workInProgress . mode ;
28222837 const primaryChildProps : OffscreenProps = {
2823- mode : 'hidden ' ,
2838+ mode : 'visible ' ,
28242839 children : primaryChildren ,
28252840 } ;
28262841 const primaryChildFragment = mountWorkInProgressOffscreenFiber (
@@ -3095,7 +3110,7 @@ function updateDehydratedSuspenseComponent(
30953110 renderLanes ,
30963111 ) ;
30973112 workInProgress . memoizedState = SUSPENDED_MARKER ;
3098- return workInProgress . child ;
3113+ return bailoutOffscreenComponent ( null , primaryChildFragment ) ;
30993114 }
31003115 }
31013116}
0 commit comments