Skip to content

Commit 08de5b1

Browse files
committed
Unify switches when hydrating
We don't really do anything between init and post mount, other than scheduling for later. So there's no behavior difference.
1 parent 9c3ef63 commit 08de5b1

File tree

1 file changed

+46
-57
lines changed

1 file changed

+46
-57
lines changed

packages/react-dom-bindings/src/client/ReactDOMComponent.js

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ function setProp(
292292
key: string,
293293
value: mixed,
294294
isCustomComponentTag: boolean,
295-
rawProps: any,
295+
props: any,
296296
): void {
297297
switch (key) {
298298
case 'style': {
@@ -325,7 +325,7 @@ function setProp(
325325
}
326326
const nextHtml: any = value.__html;
327327
if (nextHtml != null) {
328-
if (rawProps.children != null) {
328+
if (props.children != null) {
329329
throw new Error(
330330
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.',
331331
);
@@ -1093,15 +1093,15 @@ function diffHydratedStyles(domElement: Element, value: mixed) {
10931093
function diffHydratedCustomComponent(
10941094
domElement: Element,
10951095
tag: string,
1096-
rawProps: Object,
1096+
props: Object,
10971097
parentNamespaceDev: string,
10981098
extraAttributeNames: Set<string>,
10991099
) {
1100-
for (const propKey in rawProps) {
1101-
if (!rawProps.hasOwnProperty(propKey)) {
1100+
for (const propKey in props) {
1101+
if (!props.hasOwnProperty(propKey)) {
11021102
continue;
11031103
}
1104-
const nextProp = rawProps[propKey];
1104+
const nextProp = props[propKey];
11051105
if (nextProp == null) {
11061106
continue;
11071107
}
@@ -1111,7 +1111,7 @@ function diffHydratedCustomComponent(
11111111
}
11121112
continue;
11131113
}
1114-
if (rawProps.suppressHydrationWarning === true) {
1114+
if (props.suppressHydrationWarning === true) {
11151115
// Don't bother comparing. We're ignoring all these warnings.
11161116
continue;
11171117
}
@@ -1184,15 +1184,15 @@ function diffHydratedCustomComponent(
11841184
function diffHydratedGenericElement(
11851185
domElement: Element,
11861186
tag: string,
1187-
rawProps: Object,
1187+
props: Object,
11881188
parentNamespaceDev: string,
11891189
extraAttributeNames: Set<string>,
11901190
) {
1191-
for (const propKey in rawProps) {
1192-
if (!rawProps.hasOwnProperty(propKey)) {
1191+
for (const propKey in props) {
1192+
if (!props.hasOwnProperty(propKey)) {
11931193
continue;
11941194
}
1195-
const nextProp = rawProps[propKey];
1195+
const nextProp = props[propKey];
11961196
if (nextProp == null) {
11971197
continue;
11981198
}
@@ -1202,7 +1202,7 @@ function diffHydratedGenericElement(
12021202
}
12031203
continue;
12041204
}
1205-
if (rawProps.suppressHydrationWarning === true) {
1205+
if (props.suppressHydrationWarning === true) {
12061206
// Don't bother comparing. We're ignoring all these warnings.
12071207
continue;
12081208
}
@@ -1288,13 +1288,13 @@ function diffHydratedGenericElement(
12881288
export function diffHydratedProperties(
12891289
domElement: Element,
12901290
tag: string,
1291-
rawProps: Object,
1291+
props: Object,
12921292
isConcurrentMode: boolean,
12931293
shouldWarnDev: boolean,
12941294
parentNamespaceDev: string,
12951295
): null | Array<mixed> {
12961296
if (__DEV__) {
1297-
validatePropertiesInDevelopment(tag, rawProps);
1297+
validatePropertiesInDevelopment(tag, props);
12981298
}
12991299

13001300
// TODO: Make sure that we check isMounted before firing any of these events.
@@ -1337,35 +1337,44 @@ export function diffHydratedProperties(
13371337
listenToNonDelegatedEvent('toggle', domElement);
13381338
break;
13391339
case 'input':
1340-
ReactDOMInputInitWrapperState(domElement, rawProps);
1340+
ReactDOMInputInitWrapperState(domElement, props);
13411341
// We listen to this event in case to ensure emulated bubble
13421342
// listeners still fire for the invalid event.
13431343
listenToNonDelegatedEvent('invalid', domElement);
1344+
// TODO: Make sure we check if this is still unmounted or do any clean
1345+
// up necessary since we never stop tracking anymore.
1346+
track((domElement: any));
1347+
// For input and textarea we current always set the value property at
1348+
// post mount to force it to diverge from attributes. However, for
1349+
// option and select we don't quite do the same thing and select
1350+
// is not resilient to the DOM state changing so we don't do that here.
1351+
// TODO: Consider not doing this for input and textarea.
1352+
ReactDOMInputPostMountWrapper(domElement, props, true);
13441353
break;
13451354
case 'option':
1346-
ReactDOMOptionValidateProps(domElement, rawProps);
1355+
ReactDOMOptionValidateProps(domElement, props);
13471356
break;
13481357
case 'select':
1349-
ReactDOMSelectInitWrapperState(domElement, rawProps);
1358+
ReactDOMSelectInitWrapperState(domElement, props);
13501359
// We listen to this event in case to ensure emulated bubble
13511360
// listeners still fire for the invalid event.
13521361
listenToNonDelegatedEvent('invalid', domElement);
13531362
break;
13541363
case 'textarea':
1355-
ReactDOMTextareaInitWrapperState(domElement, rawProps);
1364+
ReactDOMTextareaInitWrapperState(domElement, props);
13561365
// We listen to this event in case to ensure emulated bubble
13571366
// listeners still fire for the invalid event.
13581367
listenToNonDelegatedEvent('invalid', domElement);
1368+
// TODO: Make sure we check if this is still unmounted or do any clean
1369+
// up necessary since we never stop tracking anymore.
1370+
track((domElement: any));
1371+
ReactDOMTextareaPostMountWrapper(domElement, props);
13591372
break;
13601373
}
13611374

1362-
if (rawProps.hasOwnProperty('onScroll')) {
1363-
listenToNonDelegatedEvent('scroll', domElement);
1364-
}
1365-
13661375
let updatePayload = null;
13671376

1368-
const children = rawProps.children;
1377+
const children = props.children;
13691378
// For text content children we compare against textContent. This
13701379
// might match additional HTML that is hidden when we read it using
13711380
// textContent. E.g. "foo" will match "f<span>oo</span>" but that still
@@ -1377,7 +1386,7 @@ export function diffHydratedProperties(
13771386
// TODO: Should we use domElement.firstChild.nodeValue to compare?
13781387
if (typeof children === 'string' || typeof children === 'number') {
13791388
if (domElement.textContent !== '' + children) {
1380-
if (rawProps.suppressHydrationWarning !== true) {
1389+
if (props.suppressHydrationWarning !== true) {
13811390
checkForUnmatchedText(
13821391
domElement.textContent,
13831392
children,
@@ -1391,6 +1400,15 @@ export function diffHydratedProperties(
13911400
}
13921401
}
13931402

1403+
if (props.onScroll != null) {
1404+
listenToNonDelegatedEvent('scroll', domElement);
1405+
}
1406+
1407+
if (props.onClick != null) {
1408+
// TODO: This cast may not be sound for SVG, MathML or custom elements.
1409+
trapClickOnNonInteractiveElement(((domElement: any): HTMLElement));
1410+
}
1411+
13941412
if (__DEV__ && shouldWarnDev) {
13951413
const extraAttributeNames: Set<string> = new Set();
13961414
const attributes = domElement.attributes;
@@ -1411,60 +1429,31 @@ export function diffHydratedProperties(
14111429
extraAttributeNames.add(attributes[i].name);
14121430
}
14131431
}
1414-
if (isCustomComponent(tag, rawProps)) {
1432+
if (isCustomComponent(tag, props)) {
14151433
diffHydratedCustomComponent(
14161434
domElement,
14171435
tag,
1418-
rawProps,
1436+
props,
14191437
parentNamespaceDev,
14201438
extraAttributeNames,
14211439
);
14221440
} else {
14231441
diffHydratedGenericElement(
14241442
domElement,
14251443
tag,
1426-
rawProps,
1444+
props,
14271445
parentNamespaceDev,
14281446
extraAttributeNames,
14291447
);
14301448
}
14311449
if (
14321450
extraAttributeNames.size > 0 &&
1433-
rawProps.suppressHydrationWarning !== true
1451+
props.suppressHydrationWarning !== true
14341452
) {
14351453
warnForExtraAttributes(extraAttributeNames);
14361454
}
14371455
}
14381456

1439-
switch (tag) {
1440-
case 'input':
1441-
// TODO: Make sure we check if this is still unmounted or do any clean
1442-
// up necessary since we never stop tracking anymore.
1443-
track((domElement: any));
1444-
ReactDOMInputPostMountWrapper(domElement, rawProps, true);
1445-
break;
1446-
case 'textarea':
1447-
// TODO: Make sure we check if this is still unmounted or do any clean
1448-
// up necessary since we never stop tracking anymore.
1449-
track((domElement: any));
1450-
ReactDOMTextareaPostMountWrapper(domElement, rawProps);
1451-
break;
1452-
case 'select':
1453-
case 'option':
1454-
// For input and textarea we current always set the value property at
1455-
// post mount to force it to diverge from attributes. However, for
1456-
// option and select we don't quite do the same thing and select
1457-
// is not resilient to the DOM state changing so we don't do that here.
1458-
// TODO: Consider not doing this for input and textarea.
1459-
break;
1460-
default:
1461-
if (typeof rawProps.onClick === 'function') {
1462-
// TODO: This cast may not be sound for SVG, MathML or custom elements.
1463-
trapClickOnNonInteractiveElement(((domElement: any): HTMLElement));
1464-
}
1465-
break;
1466-
}
1467-
14681457
return updatePayload;
14691458
}
14701459

0 commit comments

Comments
 (0)