Skip to content

Commit

Permalink
Add more context for insertions
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Apr 4, 2022
1 parent 05d8949 commit bdea0dc
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 44 deletions.
189 changes: 165 additions & 24 deletions packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,14 @@ describe('ReactDOMServerHydration', () => {
it('warns when client renders an extra element as only child', () => {
function Mismatch({isClient}) {
return (
<div className="parent" style={{ opacity: 1}} onClick={() => {}}>
{isClient && <main className="only" style={{ opacity: 1 }} onClick={() => {}} />}
<div className="parent" style={{opacity: 1}} onClick={() => {}}>
{isClient && (
<main
className="only"
style={{opacity: 1}}
onClick={() => {}}
/>
)}
</div>
);
}
Expand All @@ -267,7 +273,12 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\" style=\\"opacity:1\\">
+ <main className=\\"only\\" style={{\\"opacity\\":1}} /> <-- client
</div>
in main (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -279,7 +290,12 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\" style=\\"opacity:1\\">
+ <main className=\\"only\\" style={{\\"opacity\\":1}} /> <-- client
</div>
in main (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -304,7 +320,13 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <header> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
- <main class=\\"2\\" /> <-- server
+ <header className=\\"1\\" /> <-- client
...
</div>
in header (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -316,7 +338,14 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <header> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
<footer class=\\"3\\" />
+ <header className=\\"1\\" /> <-- client
</div>
in header (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -341,7 +370,14 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
<header class=\\"1\\" />
- <footer class=\\"3\\" /> <-- server
+ <main className=\\"2\\" /> <-- client
...
</div>
in main (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -353,7 +389,14 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
<footer class=\\"3\\" />
+ <main className=\\"2\\" /> <-- client
</div>
in main (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -378,7 +421,14 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
<main class=\\"2\\" />
+ <footer className=\\"3\\" /> <-- client
</div>
in footer (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -390,7 +440,14 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
<main class=\\"2\\" />
+ <footer className=\\"3\\" /> <-- client
</div>
in footer (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -414,7 +471,13 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
one
+ <footer className=\\"2\\" /> <-- client
</div>
in footer (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -426,7 +489,13 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
one
+ <footer className=\\"2\\" /> <-- client
</div>
in footer (at **)
in div (at **)
in Mismatch (at **)",
Expand Down Expand Up @@ -651,7 +720,7 @@ describe('ReactDOMServerHydration', () => {
});

// @gate __DEV__
fit('warns when server renders an extra element in the beginning', () => {
it('warns when server renders an extra element in the beginning', () => {
function Mismatch({isClient}) {
return (
<div className="parent">
Expand All @@ -661,12 +730,19 @@ describe('ReactDOMServerHydration', () => {
</div>
);
}

if (
gate(flags => flags.enableClientRenderFallbackOnHydrationMismatch)
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
- <header class=\\"1\\" /> <-- server
+ <main className=\\"2\\" /> <-- client
...
</div>
in main (at **)
in div (at **)
in Mismatch (at **)",
Expand Down Expand Up @@ -709,7 +785,14 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
<header class=\\"1\\" />
- <main class=\\"2\\" /> <-- server
+ <footer className=\\"3\\" /> <-- client
...
</div>
in footer (at **)
in div (at **)
in Mismatch (at **)",
Expand Down Expand Up @@ -882,7 +965,13 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
- first <-- server
+ <main className=\\"2\\" /> <-- client
...
</div>
in main (at **)
in div (at **)
in Mismatch (at **)",
Expand Down Expand Up @@ -925,7 +1014,14 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
<header class=\\"1\\" />
- second <-- server
+ <footer className=\\"3\\" /> <-- client
...
</div>
in footer (at **)
in div (at **)
in Mismatch (at **)",
Expand Down Expand Up @@ -1219,7 +1315,14 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
<header class=\\"1\\" />
- <footer class=\\"3\\" /> <-- server
+ <main className=\\"second\\" /> <-- client
...
</div>
in main (at **)
in Suspense (at **)
in div (at **)
Expand All @@ -1231,7 +1334,14 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <main> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
+ <main className=\\"second\\" /> <-- client
</div>
in main (at **)
in Suspense (at **)
in div (at **)
Expand Down Expand Up @@ -1259,7 +1369,14 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
<header class=\\"1\\" />
- <main class=\\"second\\" /> <-- server
+ <footer className=\\"3\\" /> <-- client
...
</div>
in footer (at **)
in Suspense (at **)
in div (at **)
Expand Down Expand Up @@ -1365,7 +1482,12 @@ describe('ReactDOMServerHydration', () => {
) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <header> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
+ <header className=\\"1\\" /> <-- client
</div>
in header (at **)
in div (at **)
in Mismatch (at **)",
Expand All @@ -1379,7 +1501,12 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <header> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
+ <header className=\\"1\\" /> <-- client
</div>
in header (at **)
in div (at **)
in Mismatch (at **)",
Expand Down Expand Up @@ -1477,7 +1604,14 @@ describe('ReactDOMServerHydration', () => {
if (gate(flags => flags.enableClientRenderFallbackOnHydrationMismatch)) {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
<main class=\\"2\\" />
+ <footer className=\\"3\\" /> <-- client
</div>
in footer (at **)
in Panel (at **)
in div (at **)
Expand All @@ -1491,7 +1625,14 @@ describe('ReactDOMServerHydration', () => {
} else {
expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
Array [
"Warning: Expected server HTML to contain a matching <footer> in <div>.
"Warning: The content rendered by the server and the client did not match because the client has rendered an extra element. The mismatch occurred inside of this parent:
<div class=\\"parent\\">
...
<main class=\\"2\\" />
+ <footer className=\\"3\\" /> <-- client
</div>
in footer (at **)
in Panel (at **)
in div (at **)
Expand Down
24 changes: 13 additions & 11 deletions packages/react-dom/src/client/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -1350,30 +1350,32 @@ function formatDiffForExtraServerNode(parentNode, child) {
function formatDiffForExtraClientNode(parentNode, tag, props, mismatchNode) {
let formattedSibling = null;
let prevSibling = null;
if (mismatchNode !== null) {
if (mismatchNode != null) {
prevSibling = findPreviousSiblingForDiff(mismatchNode);
} else if (parentNode.lastChild !== null) {
prevSibling = parentNode.lastChild;
}
let formattedChildren = '';
if (prevSibling !== null) {
formattedSibling = formatNode(prevSibling, ' ');
}
let formattedChildren = '';
if (formattedSibling !== null) {
if (findPreviousSiblingForDiff(prevSibling) !== null) {
formattedChildren += ' ...\n';
if (formattedSibling !== null) {
if (findPreviousSiblingForDiff(prevSibling) !== null) {
formattedChildren += ' ...\n';
}
formattedChildren += formattedSibling + '\n';
}
formattedChildren += formattedSibling + '\n';
}
if (mismatchNode != null) {
formattedChildren += formatNode(mismatchNode, '- ') + ' <-- server\n';
}
formattedChildren += formatReactElement(tag, props, '+ ');
formattedChildren += ' <-- client';
if (mismatchNode !== null) {
formattedChildren += '\n ...';
formattedChildren += ' <-- client\n';
if (mismatchNode != null) {
formattedChildren += ' ...';
}
return formatElement(parentNode, ' ', formattedChildren);
}


export function warnForDeletedHydratableElement(
parentNode: Element | Document | DocumentFragment,
child: Element,
Expand Down
Loading

0 comments on commit bdea0dc

Please sign in to comment.