@@ -2701,6 +2701,76 @@ export function attach(
27012701 }
27022702 }
27032703
2704+ function isChildOf(
2705+ parentInstance: DevToolsInstance,
2706+ childInstance: DevToolsInstance,
2707+ grandParent: DevToolsInstance,
2708+ ): boolean {
2709+ let instance = childInstance.parent;
2710+ while (instance !== null) {
2711+ if (parentInstance === instance) {
2712+ return true;
2713+ }
2714+ if (instance === parentInstance.parent || instance === grandParent) {
2715+ // This was a sibling but not inside the FiberInstance. We can bail out.
2716+ break;
2717+ }
2718+ instance = instance.parent;
2719+ }
2720+ return false;
2721+ }
2722+
2723+ function consumeSuspenseNodesOfExistingInstance(
2724+ instance: DevToolsInstance,
2725+ ): void {
2726+ // We need to also consume any unchanged Suspense boundaries.
2727+ let suspenseNode = remainingReconcilingChildrenSuspenseNodes;
2728+ if (suspenseNode === null) {
2729+ return;
2730+ }
2731+ const parentSuspenseNode = reconcilingParentSuspenseNode;
2732+ if (parentSuspenseNode === null) {
2733+ throw new Error(
2734+ 'The should not be any remaining suspense node children if there is no parent.',
2735+ );
2736+ }
2737+ let foundOne = false;
2738+ let previousSkippedSibling = null;
2739+ while (suspenseNode !== null) {
2740+ // Check if this SuspenseNode was a child of the bailed out FiberInstance.
2741+ if (
2742+ isChildOf(instance, suspenseNode.instance, parentSuspenseNode.instance)
2743+ ) {
2744+ foundOne = true;
2745+ // The suspenseNode was child of the bailed out Fiber.
2746+ // First, remove it from the remaining children set.
2747+ const nextRemainingSibling = suspenseNode.nextSibling;
2748+ if (previousSkippedSibling === null) {
2749+ remainingReconcilingChildrenSuspenseNodes = nextRemainingSibling;
2750+ } else {
2751+ previousSkippedSibling.nextSibling = nextRemainingSibling;
2752+ }
2753+ suspenseNode.nextSibling = null;
2754+ // Then, re-insert it into the newly reconciled set.
2755+ if (previouslyReconciledSiblingSuspenseNode === null) {
2756+ parentSuspenseNode.firstChild = suspenseNode;
2757+ } else {
2758+ previouslyReconciledSiblingSuspenseNode.nextSibling = suspenseNode;
2759+ }
2760+ previouslyReconciledSiblingSuspenseNode = suspenseNode;
2761+ // Continue
2762+ suspenseNode = nextRemainingSibling;
2763+ } else if (foundOne) {
2764+ // If we found one and then hit a miss, we assume that we're passed the sequence because
2765+ // they should've all been consecutive.
2766+ break;
2767+ } else {
2768+ previousSkippedSibling = suspenseNode;
2769+ suspenseNode = suspenseNode.nextSibling;
2770+ }
2771+ }
2772+ }
2773+
27042774 function mountVirtualInstanceRecursively(
27052775 virtualInstance: VirtualInstance,
27062776 firstChild: Fiber,
@@ -3094,9 +3164,11 @@ export function attach(
30943164 reconcilingParent = stashedParent;
30953165 previouslyReconciledSibling = stashedPrevious;
30963166 remainingReconcilingChildren = stashedRemaining;
3097- reconcilingParentSuspenseNode = stashedSuspenseParent;
3098- previouslyReconciledSiblingSuspenseNode = stashedSuspensePrevious;
3099- remainingReconcilingChildrenSuspenseNodes = stashedSuspenseRemaining;
3167+ if (instance.suspenseNode !== null) {
3168+ reconcilingParentSuspenseNode = stashedSuspenseParent;
3169+ previouslyReconciledSiblingSuspenseNode = stashedSuspensePrevious;
3170+ remainingReconcilingChildrenSuspenseNodes = stashedSuspenseRemaining;
3171+ }
31003172 }
31013173 if (instance.kind === FIBER_INSTANCE) {
31023174 recordUnmount(instance);
@@ -3688,10 +3760,12 @@ export function attach(
36883760 fiberInstance.firstChild = null;
36893761 fiberInstance.suspendedBy = null;
36903762
3691- if (fiberInstance.suspenseNode !== null) {
3692- reconcilingParentSuspenseNode = fiberInstance.suspenseNode;
3763+ const suspenseNode = fiberInstance.suspenseNode;
3764+ if (suspenseNode !== null) {
3765+ reconcilingParentSuspenseNode = suspenseNode;
36933766 previouslyReconciledSiblingSuspenseNode = null;
3694- remainingReconcilingChildrenSuspenseNodes = null;
3767+ remainingReconcilingChildrenSuspenseNodes = suspenseNode.firstChild;
3768+ suspenseNode.firstChild = null;
36953769 }
36963770 }
36973771 try {
@@ -3849,6 +3923,8 @@ export function attach(
38493923 fiberInstance.firstChild = remainingReconcilingChildren;
38503924 remainingReconcilingChildren = null;
38513925
3926+ consumeSuspenseNodesOfExistingInstance(fiberInstance);
3927+
38523928 if (traceUpdatesEnabled) {
38533929 // If we're tracing updates and we've bailed out before reaching a host node,
38543930 // we should fall back to recursively marking the nearest host descendants for highlight.
@@ -3919,9 +3995,11 @@ export function attach(
39193995 reconcilingParent = stashedParent;
39203996 previouslyReconciledSibling = stashedPrevious;
39213997 remainingReconcilingChildren = stashedRemaining;
3922- reconcilingParentSuspenseNode = stashedSuspenseParent;
3923- previouslyReconciledSiblingSuspenseNode = stashedSuspensePrevious;
3924- remainingReconcilingChildrenSuspenseNodes = stashedSuspenseRemaining;
3998+ if (fiberInstance.suspenseNode !== null) {
3999+ reconcilingParentSuspenseNode = stashedSuspenseParent;
4000+ previouslyReconciledSiblingSuspenseNode = stashedSuspensePrevious;
4001+ remainingReconcilingChildrenSuspenseNodes = stashedSuspenseRemaining;
4002+ }
39254003 }
39264004 }
39274005 }
0 commit comments