@@ -82,7 +82,10 @@ let hydrationErrors: Array<CapturedValue<mixed>> | null = null;
82
82
let rootOrSingletonContext = false ;
83
83
84
84
// Builds a common ancestor tree from the root down for collecting diffs.
85
- function buildHydrationDiffNode ( fiber : Fiber ) : HydrationDiffNode {
85
+ function buildHydrationDiffNode (
86
+ fiber : Fiber ,
87
+ distanceFromLeaf : number ,
88
+ ) : HydrationDiffNode {
86
89
if ( fiber . return === null ) {
87
90
// We're at the root.
88
91
if ( hydrationDiffRootDEV === null ) {
@@ -91,27 +94,38 @@ function buildHydrationDiffNode(fiber: Fiber): HydrationDiffNode {
91
94
children : [ ] ,
92
95
serverProps : undefined ,
93
96
serverTail : [ ] ,
97
+ distanceFromLeaf : distanceFromLeaf ,
94
98
} ;
95
99
} else if ( hydrationDiffRootDEV . fiber !== fiber ) {
96
100
throw new Error (
97
101
'Saw multiple hydration diff roots in a pass. This is a bug in React.' ,
98
102
) ;
103
+ } else if ( hydrationDiffRootDEV . distanceFromLeaf > distanceFromLeaf ) {
104
+ hydrationDiffRootDEV . distanceFromLeaf = distanceFromLeaf ;
99
105
}
100
106
return hydrationDiffRootDEV ;
101
107
}
102
- const siblings = buildHydrationDiffNode ( fiber . return ) . children ;
108
+ const siblings = buildHydrationDiffNode (
109
+ fiber . return ,
110
+ distanceFromLeaf + 1 ,
111
+ ) . children ;
103
112
// The same node may already exist in the parent. Since we currently always render depth first
104
113
// and rerender if we suspend or terminate early, if a shared ancestor was added we should still
105
114
// be inside of that shared ancestor which means it was the last one to be added. If this changes
106
115
// we may have to scan the whole set.
107
116
if ( siblings . length > 0 && siblings [ siblings . length - 1 ] . fiber === fiber ) {
108
- return siblings [ siblings . length - 1 ] ;
117
+ const existing = siblings [ siblings . length - 1 ] ;
118
+ if ( existing . distanceFromLeaf > distanceFromLeaf ) {
119
+ existing . distanceFromLeaf = distanceFromLeaf ;
120
+ }
121
+ return existing ;
109
122
}
110
123
const newNode : HydrationDiffNode = {
111
124
fiber : fiber ,
112
125
children : [ ] ,
113
126
serverProps : undefined ,
114
127
serverTail : [ ] ,
128
+ distanceFromLeaf : distanceFromLeaf ,
115
129
} ;
116
130
siblings . push ( newNode ) ;
117
131
return newNode ;
@@ -202,7 +216,7 @@ function warnNonHydratedInstance(
202
216
}
203
217
204
218
// Add this fiber to the diff tree.
205
- const diffNode = buildHydrationDiffNode ( fiber ) ;
219
+ const diffNode = buildHydrationDiffNode ( fiber , 0 ) ;
206
220
// We use null as a signal that there was no node to match.
207
221
diffNode . serverProps = null ;
208
222
if ( rejectedCandidate !== null ) {
@@ -429,7 +443,7 @@ function prepareToHydrateHostInstance(
429
443
hostContext ,
430
444
) ;
431
445
if ( differences !== null ) {
432
- const diffNode = buildHydrationDiffNode ( fiber ) ;
446
+ const diffNode = buildHydrationDiffNode ( fiber , 0 ) ;
433
447
diffNode . serverProps = differences ;
434
448
}
435
449
}
@@ -473,7 +487,7 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): void {
473
487
parentProps ,
474
488
) ;
475
489
if ( difference !== null ) {
476
- const diffNode = buildHydrationDiffNode ( fiber ) ;
490
+ const diffNode = buildHydrationDiffNode ( fiber , 0 ) ;
477
491
diffNode . serverProps = difference ;
478
492
}
479
493
}
@@ -491,7 +505,7 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): void {
491
505
parentProps ,
492
506
) ;
493
507
if ( difference !== null ) {
494
- const diffNode = buildHydrationDiffNode ( fiber ) ;
508
+ const diffNode = buildHydrationDiffNode ( fiber , 0 ) ;
495
509
diffNode . serverProps = difference ;
496
510
}
497
511
}
@@ -645,13 +659,14 @@ function warnIfUnhydratedTailNodes(fiber: Fiber) {
645
659
if ( __DEV__ ) {
646
660
let nextInstance = nextHydratableInstance ;
647
661
while ( nextInstance ) {
648
- const diffNode = buildHydrationDiffNode ( fiber ) ;
662
+ const diffNode = buildHydrationDiffNode ( fiber , 0 ) ;
649
663
const description =
650
664
describeHydratableInstanceForDevWarnings ( nextInstance ) ;
651
665
diffNode . serverTail . push ( description ) ;
652
666
if ( description . type === 'Suspense' ) {
667
+ const suspenseInstance : SuspenseInstance = ( nextInstance : any ) ;
653
668
nextInstance =
654
- getNextHydratableInstanceAfterSuspenseInstance ( nextInstance ) ;
669
+ getNextHydratableInstanceAfterSuspenseInstance ( suspenseInstance ) ;
655
670
} else {
656
671
nextInstance = getNextHydratableSibling ( nextInstance ) ;
657
672
}
0 commit comments