@@ -52,14 +52,12 @@ import {hasRole} from './DOMAccessibilityRoles';
5252import {
5353 setInitialProperties ,
5454 updateProperties ,
55+ hydrateProperties ,
56+ hydrateText ,
5557 diffHydratedProperties ,
58+ getPropsFromElement ,
5659 diffHydratedText ,
5760 trapClickOnNonInteractiveElement ,
58- checkForUnmatchedText ,
59- warnForDeletedHydratableElement ,
60- warnForDeletedHydratableText ,
61- warnForInsertedHydratedElement ,
62- warnForInsertedHydratedText ,
6361} from './ReactDOMComponent' ;
6462import { getSelectionInformation , restoreSelection } from './ReactInputSelection' ;
6563import setTextContent from './setTextContent' ;
@@ -1342,6 +1340,26 @@ export function getFirstHydratableChildWithinSuspenseInstance(
13421340 return getNextHydratable ( parentInstance . nextSibling ) ;
13431341}
13441342
1343+ export function describeHydratableInstanceForDevWarnings (
1344+ instance : HydratableInstance ,
1345+ ) : string | { type : string , props : $ReadOnly < Props > } {
1346+ // Reverse engineer a pseudo react-element from hydratable instnace
1347+ if ( instance . nodeType === ELEMENT_NODE ) {
1348+ // Reverse engineer a set of props that can print for dev warnings
1349+ return {
1350+ type : instance . nodeName . toLowerCase ( ) ,
1351+ props : getPropsFromElement ( ( instance : any ) ) ,
1352+ } ;
1353+ } else if ( instance . nodeType === COMMENT_NODE ) {
1354+ return {
1355+ type : 'Suspense' ,
1356+ props : { } ,
1357+ } ;
1358+ } else {
1359+ return instance . nodeValue ;
1360+ }
1361+ }
1362+
13451363export function validateHydratableInstance (
13461364 type : string ,
13471365 props : Props ,
@@ -1361,14 +1379,23 @@ export function hydrateInstance(
13611379 props : Props ,
13621380 hostContext : HostContext ,
13631381 internalInstanceHandle : Object ,
1364- shouldWarnDev : boolean ,
1365- ) : void {
1382+ ) : boolean {
13661383 precacheFiberNode ( internalInstanceHandle , instance ) ;
13671384 // TODO: Possibly defer this until the commit phase where all the events
13681385 // get attached.
13691386 updateFiberProps ( instance , props ) ;
13701387
1371- diffHydratedProperties ( instance , type , props , shouldWarnDev , hostContext ) ;
1388+ return hydrateProperties ( instance , type , props , hostContext ) ;
1389+ }
1390+
1391+ // Returns a Map of properties that were different on the server.
1392+ export function diffHydratedPropsForDevWarnings (
1393+ instance : Instance ,
1394+ type : string ,
1395+ props : Props ,
1396+ hostContext : HostContext ,
1397+ ) : null | $ReadOnly < Props > {
1398+ return diffHydratedProperties ( instance , type , props , hostContext ) ;
13721399}
13731400
13741401export function validateHydratableTextInstance (
@@ -1389,11 +1416,26 @@ export function hydrateTextInstance(
13891416 textInstance : TextInstance ,
13901417 text : string ,
13911418 internalInstanceHandle : Object ,
1392- shouldWarnDev : boolean ,
1419+ parentInstanceProps : null | Props ,
13931420) : boolean {
13941421 precacheFiberNode ( internalInstanceHandle , textInstance ) ;
13951422
1396- return diffHydratedText ( textInstance , text ) ;
1423+ return hydrateText ( textInstance , text , parentInstanceProps ) ;
1424+ }
1425+
1426+ // Returns the server text if it differs from the client.
1427+ export function diffHydratedTextForDevWarnings (
1428+ textInstance : TextInstance ,
1429+ text : string ,
1430+ parentProps : null | Props ,
1431+ ) : null | string {
1432+ if (
1433+ parentProps === null ||
1434+ parentProps [ SUPPRESS_HYDRATION_WARNING ] !== true
1435+ ) {
1436+ return diffHydratedText ( textInstance , text ) ;
1437+ }
1438+ return null ;
13971439}
13981440
13991441export function hydrateSuspenseInstance (
@@ -1485,183 +1527,6 @@ export function shouldDeleteUnhydratedTailInstances(
14851527 return parentType !== 'form' && parentType !== 'button' ;
14861528}
14871529
1488- export function didNotMatchHydratedContainerTextInstance (
1489- parentContainer : Container ,
1490- textInstance : TextInstance ,
1491- text : string ,
1492- shouldWarnDev : boolean ,
1493- ) {
1494- checkForUnmatchedText ( textInstance . nodeValue , text , shouldWarnDev ) ;
1495- }
1496-
1497- export function didNotMatchHydratedTextInstance (
1498- parentType : string ,
1499- parentProps : Props ,
1500- parentInstance : Instance ,
1501- textInstance : TextInstance ,
1502- text : string ,
1503- shouldWarnDev : boolean ,
1504- ) {
1505- if ( parentProps [ SUPPRESS_HYDRATION_WARNING ] !== true ) {
1506- checkForUnmatchedText ( textInstance . nodeValue , text , shouldWarnDev ) ;
1507- }
1508- }
1509-
1510- export function didNotHydrateInstanceWithinContainer (
1511- parentContainer : Container ,
1512- instance : HydratableInstance ,
1513- ) {
1514- if ( __DEV__ ) {
1515- if ( instance . nodeType === ELEMENT_NODE ) {
1516- warnForDeletedHydratableElement ( parentContainer , ( instance : any ) ) ;
1517- } else if ( instance . nodeType === COMMENT_NODE ) {
1518- // TODO: warnForDeletedHydratableSuspenseBoundary
1519- } else {
1520- warnForDeletedHydratableText ( parentContainer , ( instance : any ) ) ;
1521- }
1522- }
1523- }
1524-
1525- export function didNotHydrateInstanceWithinSuspenseInstance (
1526- parentInstance : SuspenseInstance ,
1527- instance : HydratableInstance ,
1528- ) {
1529- if ( __DEV__ ) {
1530- // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes.
1531- const parentNode : Element | Document | null = parentInstance . parentNode ;
1532- if ( parentNode !== null ) {
1533- if ( instance . nodeType === ELEMENT_NODE ) {
1534- warnForDeletedHydratableElement ( parentNode , ( instance : any ) ) ;
1535- } else if ( instance . nodeType === COMMENT_NODE ) {
1536- // TODO: warnForDeletedHydratableSuspenseBoundary
1537- } else {
1538- warnForDeletedHydratableText ( parentNode , ( instance : any ) ) ;
1539- }
1540- }
1541- }
1542- }
1543-
1544- export function didNotHydrateInstance (
1545- parentType : string ,
1546- parentProps : Props ,
1547- parentInstance : Instance ,
1548- instance : HydratableInstance ,
1549- ) {
1550- if ( __DEV__ ) {
1551- if ( instance . nodeType === ELEMENT_NODE ) {
1552- warnForDeletedHydratableElement ( parentInstance , ( instance : any ) ) ;
1553- } else if ( instance . nodeType === COMMENT_NODE ) {
1554- // TODO: warnForDeletedHydratableSuspenseBoundary
1555- } else {
1556- warnForDeletedHydratableText ( parentInstance , ( instance : any ) ) ;
1557- }
1558- }
1559- }
1560-
1561- export function didNotFindHydratableInstanceWithinContainer (
1562- parentContainer : Container ,
1563- type : string ,
1564- props : Props ,
1565- ) {
1566- if ( __DEV__ ) {
1567- warnForInsertedHydratedElement ( parentContainer , type , props ) ;
1568- }
1569- }
1570-
1571- export function didNotFindHydratableTextInstanceWithinContainer (
1572- parentContainer : Container ,
1573- text : string ,
1574- ) {
1575- if ( __DEV__ ) {
1576- warnForInsertedHydratedText ( parentContainer , text ) ;
1577- }
1578- }
1579-
1580- export function didNotFindHydratableSuspenseInstanceWithinContainer (
1581- parentContainer : Container ,
1582- ) {
1583- if ( __DEV__ ) {
1584- // TODO: warnForInsertedHydratedSuspense(parentContainer);
1585- }
1586- }
1587-
1588- export function didNotFindHydratableInstanceWithinSuspenseInstance (
1589- parentInstance : SuspenseInstance ,
1590- type : string ,
1591- props : Props ,
1592- ) {
1593- if ( __DEV__ ) {
1594- // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes.
1595- const parentNode : Element | Document | null = parentInstance . parentNode ;
1596- if ( parentNode !== null )
1597- warnForInsertedHydratedElement ( parentNode , type , props ) ;
1598- }
1599- }
1600-
1601- export function didNotFindHydratableTextInstanceWithinSuspenseInstance (
1602- parentInstance : SuspenseInstance ,
1603- text : string ,
1604- ) {
1605- if ( __DEV__ ) {
1606- // $FlowFixMe[incompatible-type]: Only Element or Document can be parent nodes.
1607- const parentNode : Element | Document | null = parentInstance . parentNode ;
1608- if ( parentNode !== null ) warnForInsertedHydratedText ( parentNode , text ) ;
1609- }
1610- }
1611-
1612- export function didNotFindHydratableSuspenseInstanceWithinSuspenseInstance (
1613- parentInstance : SuspenseInstance ,
1614- ) {
1615- if ( __DEV__ ) {
1616- // const parentNode: Element | Document | null = parentInstance.parentNode;
1617- // TODO: warnForInsertedHydratedSuspense(parentNode);
1618- }
1619- }
1620-
1621- export function didNotFindHydratableInstance (
1622- parentType : string ,
1623- parentProps : Props ,
1624- parentInstance : Instance ,
1625- type : string ,
1626- props : Props ,
1627- ) {
1628- if ( __DEV__ ) {
1629- warnForInsertedHydratedElement ( parentInstance , type , props ) ;
1630- }
1631- }
1632-
1633- export function didNotFindHydratableTextInstance (
1634- parentType : string ,
1635- parentProps : Props ,
1636- parentInstance : Instance ,
1637- text : string ,
1638- ) {
1639- if ( __DEV__ ) {
1640- warnForInsertedHydratedText ( parentInstance , text ) ;
1641- }
1642- }
1643-
1644- export function didNotFindHydratableSuspenseInstance (
1645- parentType : string ,
1646- parentProps : Props ,
1647- parentInstance : Instance ,
1648- ) {
1649- if ( __DEV__ ) {
1650- // TODO: warnForInsertedHydratedSuspense(parentInstance);
1651- }
1652- }
1653-
1654- export function errorHydratingContainer ( parentContainer : Container ) : void {
1655- if ( __DEV__ ) {
1656- // TODO: This gets logged by onRecoverableError, too, so we should be
1657- // able to remove it.
1658- console . error (
1659- 'An error occurred during hydration. The server HTML was replaced with client content in <%s>.' ,
1660- parentContainer . nodeName . toLowerCase ( ) ,
1661- ) ;
1662- }
1663- }
1664-
16651530// -------------------
16661531// Test Selectors
16671532// -------------------
0 commit comments