@@ -2701,6 +2701,76 @@ export function attach(
2701
2701
}
2702
2702
}
2703
2703
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
+
2704
2774
function mountVirtualInstanceRecursively(
2705
2775
virtualInstance: VirtualInstance,
2706
2776
firstChild: Fiber,
@@ -3094,9 +3164,11 @@ export function attach(
3094
3164
reconcilingParent = stashedParent;
3095
3165
previouslyReconciledSibling = stashedPrevious;
3096
3166
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
+ }
3100
3172
}
3101
3173
if (instance.kind === FIBER_INSTANCE) {
3102
3174
recordUnmount(instance);
@@ -3688,10 +3760,12 @@ export function attach(
3688
3760
fiberInstance.firstChild = null;
3689
3761
fiberInstance.suspendedBy = null;
3690
3762
3691
- if (fiberInstance.suspenseNode !== null) {
3692
- reconcilingParentSuspenseNode = fiberInstance.suspenseNode;
3763
+ const suspenseNode = fiberInstance.suspenseNode;
3764
+ if (suspenseNode !== null) {
3765
+ reconcilingParentSuspenseNode = suspenseNode;
3693
3766
previouslyReconciledSiblingSuspenseNode = null;
3694
- remainingReconcilingChildrenSuspenseNodes = null;
3767
+ remainingReconcilingChildrenSuspenseNodes = suspenseNode.firstChild;
3768
+ suspenseNode.firstChild = null;
3695
3769
}
3696
3770
}
3697
3771
try {
@@ -3849,6 +3923,8 @@ export function attach(
3849
3923
fiberInstance.firstChild = remainingReconcilingChildren;
3850
3924
remainingReconcilingChildren = null;
3851
3925
3926
+ consumeSuspenseNodesOfExistingInstance(fiberInstance);
3927
+
3852
3928
if (traceUpdatesEnabled) {
3853
3929
// If we're tracing updates and we've bailed out before reaching a host node,
3854
3930
// we should fall back to recursively marking the nearest host descendants for highlight.
@@ -3919,9 +3995,11 @@ export function attach(
3919
3995
reconcilingParent = stashedParent;
3920
3996
previouslyReconciledSibling = stashedPrevious;
3921
3997
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
+ }
3925
4003
}
3926
4004
}
3927
4005
}
0 commit comments