75
canHydrateFormStateMarker,
76
isFormStateMarkerMatching,
77
isHydratableText,
78
+ validateHydratableInstance,
79
+ validateHydratableTextInstance,
80
} from './ReactFiberConfig';
81
import {OffscreenLane} from './ReactFiberLane';
82
import {
204
returnFiber: Fiber,
205
instance: HydratableInstance,
206
) {
205
- warnUnhydratedInstance(returnFiber, instance);
207
const childToDelete = createFiberFromHostInstanceForDeletion();
208
childToDelete.stateNode = instance;
209
childToDelete.return = returnFiber;
217
}
218
}
219
219
-function warnNonhydratedInstance(returnFiber: Fiber, fiber: Fiber) {
220
+function warnNonHydratedInstance(returnFiber: Fiber, fiber: Fiber) {
221
if (__DEV__) {
222
if (didSuspendOrErrorDEV) {
223
// Inside a boundary that already suspended. We're currently rendering the
340
}
341
function insertNonHydratedInstance(returnFiber: Fiber, fiber: Fiber) {
342
fiber.flags = (fiber.flags & ~Hydrating) | Placement;
342
- warnNonhydratedInstance(returnFiber, fiber);
343
}
344
345
function tryHydrateInstance(fiber: Fiber, nextInstance: any) {
446
if (!isHydrating) {
447
return;
448
}
449
+
450
+ // Validate that this is ok to render here before any mismatches.
451
+ const currentHostContext = getHostContext();
452
+ const shouldKeepWarning = validateHydratableInstance(
453
+ fiber.type,
454
+ fiber.pendingProps,
455
+ currentHostContext,
456
+ );
457
+
458
const initialInstance = nextHydratableInstance;
459
const nextInstance = nextHydratableInstance;
460
if (!nextInstance) {
461
if (shouldClientRenderOnMismatch(fiber)) {
453
- warnNonhydratedInstance((hydrationParentFiber: any), fiber);
462
+ if (shouldKeepWarning) {
463
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
464
+ }
465
throwOnHydrationMismatch(fiber);
466
}
467
// Nothing to hydrate. Make it an insertion.
468
insertNonHydratedInstance((hydrationParentFiber: any), fiber);
469
+ if (shouldKeepWarning) {
470
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
471
+ }
472
isHydrating = false;
473
hydrationParentFiber = fiber;
474
nextHydratableInstance = initialInstance;
477
const firstAttemptedInstance = nextInstance;
478
if (!tryHydrateInstance(fiber, nextInstance)) {
479
if (shouldClientRenderOnMismatch(fiber)) {
466
- warnNonhydratedInstance((hydrationParentFiber: any), fiber);
480
+ if (shouldKeepWarning) {
481
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
482
+ }
483
throwOnHydrationMismatch(fiber);
484
}
485
// If we can't hydrate this instance let's try the next one.
493
) {
494
// Nothing to hydrate. Make it an insertion.
495
insertNonHydratedInstance((hydrationParentFiber: any), fiber);
496
+ if (shouldKeepWarning) {
497
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
498
+ }
499
isHydrating = false;
500
hydrationParentFiber = fiber;
501
nextHydratableInstance = initialInstance;
505
// superfluous and we'll delete it. Since we can't eagerly delete it
506
// we'll have to schedule a deletion. To do that, this node needs a dummy
507
// fiber associated with it.
508
+ if (shouldKeepWarning) {
509
+ warnUnhydratedInstance(prevHydrationParentFiber, firstAttemptedInstance);
510
+ }
511
deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
512
}
513
}
519
const text = fiber.pendingProps;
520
const isHydratable = isHydratableText(text);
521
522
+ let shouldKeepWarning = true;
523
+ if (isHydratable) {
524
+ // Validate that this is ok to render here before any mismatches.
525
+ const currentHostContext = getHostContext();
526
+ shouldKeepWarning = validateHydratableTextInstance(
527
+ text,
528
+ currentHostContext,
529
+ );
530
+ }
531
+
532
const initialInstance = nextHydratableInstance;
533
const nextInstance = nextHydratableInstance;
534
if (!nextInstance || !isHydratable) {
535
// We exclude non hydrabable text because we know there are no matching hydratables.
536
// We either throw or insert depending on the render mode.
537
if (shouldClientRenderOnMismatch(fiber)) {
506
- warnNonhydratedInstance((hydrationParentFiber: any), fiber);
538
+ if (shouldKeepWarning) {
539
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
540
+ }
541
throwOnHydrationMismatch(fiber);
542
}
543
// Nothing to hydrate. Make it an insertion.
544
insertNonHydratedInstance((hydrationParentFiber: any), fiber);
545
+ if (shouldKeepWarning) {
546
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
547
+ }
548
isHydrating = false;
549
hydrationParentFiber = fiber;
550
nextHydratableInstance = initialInstance;
553
const firstAttemptedInstance = nextInstance;
554
if (!tryHydrateText(fiber, nextInstance)) {
555
if (shouldClientRenderOnMismatch(fiber)) {
519
- warnNonhydratedInstance((hydrationParentFiber: any), fiber);
556
+ if (shouldKeepWarning) {
557
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
558
+ }
559
throwOnHydrationMismatch(fiber);
560
}
561
// If we can't hydrate this instance let's try the next one.
570
) {
571
// Nothing to hydrate. Make it an insertion.
572
insertNonHydratedInstance((hydrationParentFiber: any), fiber);
573
+ if (shouldKeepWarning) {
574
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
575
+ }
576
isHydrating = false;
577
hydrationParentFiber = fiber;
578
nextHydratableInstance = initialInstance;
582
// superfluous and we'll delete it. Since we can't eagerly delete it
583
// we'll have to schedule a deletion. To do that, this node needs a dummy
584
// fiber associated with it.
585
+ if (shouldKeepWarning) {
586
+ warnUnhydratedInstance(prevHydrationParentFiber, firstAttemptedInstance);
587
+ }
588
deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
589
}
590
}
597
const nextInstance = nextHydratableInstance;
598
if (!nextInstance) {
599
if (shouldClientRenderOnMismatch(fiber)) {
555
- warnNonhydratedInstance((hydrationParentFiber: any), fiber);
600
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
601
throwOnHydrationMismatch(fiber);
602
}
603
// Nothing to hydrate. Make it an insertion.
604
insertNonHydratedInstance((hydrationParentFiber: any), fiber);
605
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
606
isHydrating = false;
607
hydrationParentFiber = fiber;
608
nextHydratableInstance = initialInstance;
611
const firstAttemptedInstance = nextInstance;
612
if (!tryHydrateSuspense(fiber, nextInstance)) {
613
if (shouldClientRenderOnMismatch(fiber)) {
568
- warnNonhydratedInstance((hydrationParentFiber: any), fiber);
614
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
615
throwOnHydrationMismatch(fiber);
616
}
617
// If we can't hydrate this instance let's try the next one.
626
) {
627
// Nothing to hydrate. Make it an insertion.
628
insertNonHydratedInstance((hydrationParentFiber: any), fiber);
629
+ warnNonHydratedInstance((hydrationParentFiber: any), fiber);
630
isHydrating = false;
631
hydrationParentFiber = fiber;
632
nextHydratableInstance = initialInstance;
636
// superfluous and we'll delete it. Since we can't eagerly delete it
637
// we'll have to schedule a deletion. To do that, this node needs a dummy
638
// fiber associated with it.
639
+ warnUnhydratedInstance(prevHydrationParentFiber, firstAttemptedInstance);
640
deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
641
}
642
}
882
throwOnHydrationMismatch(fiber);
883
} else {
884
while (nextInstance) {
885
+ warnUnhydratedInstance(fiber, nextInstance);
886
deleteHydratableInstance(fiber, nextInstance);
887
nextInstance = getNextHydratableSibling(nextInstance);
888
}