@@ -3144,12 +3144,30 @@ export function attach(
31443144 }
31453145 }
31463146
3147+ /**
3148+ * Offscreen of suspended Suspense
3149+ */
3150+ function isSuspendedOffscreen(fiber: Fiber): boolean {
3151+ switch (fiber.tag) {
3152+ case LegacyHiddenComponent:
3153+ // fallthrough since all published implementations currently implement the same state as Offscreen.
3154+ case OffscreenComponent:
3155+ return (
3156+ fiber.memoizedState !== null &&
3157+ fiber.return !== null &&
3158+ fiber.return.tag === SuspenseComponent
3159+ );
3160+ default:
3161+ return false;
3162+ }
3163+ }
3164+
31473165 function unmountRemainingChildren() {
31483166 if (
31493167 reconcilingParent !== null &&
31503168 (reconcilingParent.kind === FIBER_INSTANCE ||
31513169 reconcilingParent.kind === FILTERED_FIBER_INSTANCE) &&
3152- isHiddenOffscreen (reconcilingParent.data) &&
3170+ isSuspendedOffscreen (reconcilingParent.data) &&
31533171 !isInDisconnectedSubtree
31543172 ) {
31553173 // This is a hidden offscreen, we need to execute this in the context of a disconnected subtree.
@@ -4026,7 +4044,7 @@ export function attach(
40264044 trackDebugInfoFromHostComponent(nearestInstance, fiber);
40274045 }
40284046
4029- if (isHiddenOffscreen (fiber)) {
4047+ if (isSuspendedOffscreen (fiber)) {
40304048 // If an Offscreen component is hidden, mount its children as disconnected.
40314049 const stashedDisconnected = isInDisconnectedSubtree;
40324050 isInDisconnectedSubtree = true;
@@ -4037,6 +4055,9 @@ export function attach(
40374055 } finally {
40384056 isInDisconnectedSubtree = stashedDisconnected;
40394057 }
4058+ } else if (isHiddenOffscreen(fiber)) {
4059+ // hidden Activity is noisy.
4060+ // Including it may show overlapping Suspense rects
40404061 } else if (fiber.tag === SuspenseComponent && OffscreenComponent === -1) {
40414062 // Legacy Suspense without the Offscreen wrapper. For the modern Suspense we just handle the
40424063 // Offscreen wrapper itself specially.
@@ -4981,6 +5002,8 @@ export function attach(
49815002
49825003 const prevWasHidden = isHiddenOffscreen(prevFiber);
49835004 const nextIsHidden = isHiddenOffscreen(nextFiber);
5005+ const prevWasSuspended = isSuspendedOffscreen(prevFiber);
5006+ const nextIsSuspended = isSuspendedOffscreen(nextFiber);
49845007
49855008 if (isLegacySuspense) {
49865009 if (
@@ -5058,8 +5081,8 @@ export function attach(
50585081 );
50595082 updateFlags |= ShouldResetChildren | ShouldResetSuspenseChildren;
50605083 }
5061- } else if (nextIsHidden ) {
5062- if (!prevWasHidden ) {
5084+ } else if (nextIsSuspended ) {
5085+ if (!prevWasSuspended ) {
50635086 // We're hiding the children. Disconnect them from the front end but keep state.
50645087 if (fiberInstance !== null && !isInDisconnectedSubtree) {
50655088 disconnectChildrenRecursively(remainingReconcilingChildren);
@@ -5077,7 +5100,7 @@ export function attach(
50775100 } finally {
50785101 isInDisconnectedSubtree = stashedDisconnected;
50795102 }
5080- } else if (prevWasHidden && !nextIsHidden ) {
5103+ } else if (prevWasSuspended && !nextIsSuspended ) {
50815104 // We're revealing the hidden children. We now need to update them to the latest state.
50825105 // We do this while still in the disconnected state and then we reconnect the new ones.
50835106 // This avoids reconnecting things that are about to be removed anyway.
@@ -5103,6 +5126,13 @@ export function attach(
51035126 // Children may have reordered while they were hidden.
51045127 updateFlags |= ShouldResetChildren | ShouldResetSuspenseChildren;
51055128 }
5129+ } else if (nextIsHidden) {
5130+ if (prevWasHidden) {
5131+ // still hidden. Nothing to do.
5132+ } else {
5133+ // We're hiding the children. Remove them from the Frontend
5134+ unmountRemainingChildren();
5135+ }
51065136 } else if (
51075137 nextFiber.tag === SuspenseComponent &&
51085138 OffscreenComponent !== -1 &&
@@ -5259,7 +5289,7 @@ export function attach(
52595289 // We need to crawl the subtree for closest non-filtered Fibers
52605290 // so that we can display them in a flat children set.
52615291 if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
5262- if (!nextIsHidden && !isInDisconnectedSubtree) {
5292+ if (!nextIsSuspended && !isInDisconnectedSubtree) {
52635293 recordResetChildren(fiberInstance);
52645294 }
52655295
@@ -5335,7 +5365,7 @@ export function attach(
53355365 if (
53365366 (child.kind === FIBER_INSTANCE ||
53375367 child.kind === FILTERED_FIBER_INSTANCE) &&
5338- isHiddenOffscreen (child.data)
5368+ isSuspendedOffscreen (child.data)
53395369 ) {
53405370 // This instance's children are already disconnected.
53415371 } else {
0 commit comments