',
'\n' +
' in div (at **)\n' +
' in Component (at **)\n' +
@@ -610,9 +610,9 @@ describe('ReactDOMServerPartialHydration', () => {
}
if (__DEV__) {
expect(mockError).toHaveBeenCalledWith(
- 'Warning: Did not expect server HTML to contain a <%s> in <%s>.%s',
- 'span',
- 'div',
+ 'Warning: Did not expect server HTML to contain a %s in %s.%s',
+ '
',
+ '',
'\n' +
' in Suspense (at **)\n' +
' in div (at **)\n' +
diff --git a/packages/react-dom/src/__tests__/ReactRenderDocument-test.js b/packages/react-dom/src/__tests__/ReactRenderDocument-test.js
index 95b814b331d..79b5af85fab 100644
--- a/packages/react-dom/src/__tests__/ReactRenderDocument-test.js
+++ b/packages/react-dom/src/__tests__/ReactRenderDocument-test.js
@@ -222,7 +222,9 @@ describe('rendering React components at document', () => {
// getTestDocument() has an extra that we didn't render.
expect(() =>
ReactDOM.hydrate(, testDocument),
- ).toErrorDev('Did not expect server HTML to contain a in .');
+ ).toErrorDev(
+ 'Did not expect server HTML to contain a in .',
+ );
expect(testDocument.body.innerHTML).toBe('Hello world');
});
diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js
index 7f9b6ac47d8..9e74a5ccff0 100644
--- a/packages/react-dom/src/client/ReactDOMComponent.js
+++ b/packages/react-dom/src/client/ReactDOMComponent.js
@@ -62,7 +62,7 @@ import {
shouldRemoveAttribute,
} from '../shared/DOMProperty';
import assertValidProps from '../shared/assertValidProps';
-import {DOCUMENT_NODE} from '../shared/HTMLNodeType';
+import {DOCUMENT_NODE, ELEMENT_NODE} from '../shared/HTMLNodeType';
import isCustomComponent from '../shared/isCustomComponent';
import possibleStandardNames from '../shared/possibleStandardNames';
import {validateProperties as validateARIAProperties} from '../shared/ReactDOMInvalidARIAHook';
@@ -100,6 +100,7 @@ let warnForInvalidEventListener;
let canDiffStyleForHydrationWarning;
let normalizeHTML;
+let formatTagDEV;
if (__DEV__) {
warnedUnknownTags = {
@@ -206,6 +207,31 @@ if (__DEV__) {
testElement.innerHTML = html;
return testElement.innerHTML;
};
+
+ formatTagDEV = function(node: Element | Document | DocumentFragment): string {
+ let str = '<' + node.nodeName.toLowerCase();
+ if (node.nodeType === ELEMENT_NODE) {
+ const element = ((node: any): Element);
+ const attributes = element.attributes;
+ for (let i = 0; i < attributes.length; i++) {
+ if (i > 30) {
+ str += ' ...';
+ break;
+ }
+ const attributeName = attributes[i].name;
+ const value = attributes[i].value;
+ if (value != null) {
+ let trimmedValue = value;
+ if (value.length > 30) {
+ trimmedValue = value.substr(0, 30) + '...';
+ }
+ str += ' ' + attributeName + '="' + trimmedValue + '"';
+ }
+ }
+ }
+ str += '>';
+ return str;
+ };
}
// HTML parsing normalizes CR and CRLF to LF.
@@ -1209,9 +1235,9 @@ export function warnForDeletedHydratableElement(
}
didWarnInvalidHydration = true;
console.error(
- 'Did not expect server HTML to contain a <%s> in <%s>.',
- child.nodeName.toLowerCase(),
- parentNode.nodeName.toLowerCase(),
+ 'Did not expect server HTML to contain a %s in %s.',
+ formatTagDEV(child),
+ formatTagDEV(parentNode),
);
}
}
@@ -1226,9 +1252,9 @@ export function warnForDeletedHydratableText(
}
didWarnInvalidHydration = true;
console.error(
- 'Did not expect server HTML to contain the text node "%s" in <%s>.',
+ 'Did not expect server HTML to contain the text node "%s" in %s.',
child.nodeValue,
- parentNode.nodeName.toLowerCase(),
+ formatTagDEV(parentNode),
);
}
}
@@ -1244,9 +1270,9 @@ export function warnForInsertedHydratedElement(
}
didWarnInvalidHydration = true;
console.error(
- 'Expected server HTML to contain a matching <%s> in <%s>.',
+ 'Expected server HTML to contain a matching <%s> in %s.',
tag,
- parentNode.nodeName.toLowerCase(),
+ formatTagDEV(parentNode),
);
}
}
@@ -1268,9 +1294,9 @@ export function warnForInsertedHydratedText(
}
didWarnInvalidHydration = true;
console.error(
- 'Expected server HTML to contain a matching text node for "%s" in <%s>.',
+ 'Expected server HTML to contain a matching text node for "%s" in %s.',
text,
- parentNode.nodeName.toLowerCase(),
+ formatTagDEV(parentNode),
);
}
}