@@ -2732,10 +2732,31 @@ export function attach(
27322732 }
27332733
27342734 function unmountRemainingChildren() {
2735- let child = remainingReconcilingChildren;
2736- while (child !== null) {
2737- unmountInstanceRecursively(child);
2738- child = remainingReconcilingChildren;
2735+ if (
2736+ reconcilingParent !== null &&
2737+ (reconcilingParent.kind === FIBER_INSTANCE ||
2738+ reconcilingParent.kind === FILTERED_FIBER_INSTANCE) &&
2739+ reconcilingParent.data.tag === OffscreenComponent &&
2740+ reconcilingParent.data.memoizedState !== null &&
2741+ !isInDisconnectedSubtree
2742+ ) {
2743+ // This is a hidden offscreen, we need to execute this in the context of a disconnected subtree.
2744+ isInDisconnectedSubtree = true;
2745+ try {
2746+ let child = remainingReconcilingChildren;
2747+ while (child !== null) {
2748+ unmountInstanceRecursively(child);
2749+ child = remainingReconcilingChildren;
2750+ }
2751+ } finally {
2752+ isInDisconnectedSubtree = false;
2753+ }
2754+ } else {
2755+ let child = remainingReconcilingChildren;
2756+ while (child !== null) {
2757+ unmountInstanceRecursively(child);
2758+ child = remainingReconcilingChildren;
2759+ }
27392760 }
27402761 }
27412762
@@ -2854,6 +2875,9 @@ export function attach(
28542875 }
28552876
28562877 function recordVirtualDisconnect(instance: VirtualInstance) {
2878+ if (isInDisconnectedSubtree) {
2879+ return;
2880+ }
28572881 if (trackedPathMatchInstance === instance) {
28582882 // We're in the process of trying to restore previous selection.
28592883 // If this fiber matched but is being unmounted, there's no use trying.
@@ -3959,12 +3983,12 @@ export function attach(
39593983 isInDisconnectedSubtree = true;
39603984 try {
39613985 if (nextFiber.child !== null) {
3962- updateChildrenRecursively(
3963- nextFiber.child,
3964- prevFiber.child,
3965- traceNearestHostComponentUpdate,
3966- );
3986+ updateChildrenRecursively(nextFiber.child, prevFiber.child, false);
39673987 }
3988+ // Ensure we unmount any remaining children inside the isInDisconnectedSubtree flag
3989+ // since they should not trigger real deletions.
3990+ unmountRemainingChildren();
3991+ remainingReconcilingChildren = null;
39683992 } finally {
39693993 isInDisconnectedSubtree = stashedDisconnected;
39703994 }
0 commit comments