From 21dde0b38ea8635fad9769e51e24bf80a1ad5e44 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Thu, 25 Mar 2021 11:00:54 -0400 Subject: [PATCH] Add separator comment between text nodes This is needed to avoid mutating the DOM during hydration. This *always* adds it even when it's just text children. We need to avoid this overhead but it's a somewhat tricky problem to solve so we defer the optimization to later. --- .../src/__tests__/ReactDOMFizzServerBrowser-test.js | 6 ++++-- .../src/__tests__/ReactDOMFizzServerNode-test.js | 12 +++++++----- .../src/server/ReactDOMServerFormatConfig.js | 9 ++++++++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js index b55bb446f6fc..a61727d7fdf0 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js @@ -55,7 +55,7 @@ describe('ReactDOMFizzServer', () => {
hello world
, ); const result = await readResult(stream); - expect(result).toBe('
hello world
'); + expect(result).toMatchInlineSnapshot(`"
hello world
"`); }); // @gate experimental @@ -93,7 +93,9 @@ describe('ReactDOMFizzServer', () => { expect(isComplete).toBe(true); const result = await readResult(stream); - expect(result).toBe('
Done
'); + expect(result).toMatchInlineSnapshot( + `"
Done
"`, + ); }); // @gate experimental diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js index 5377607a5795..c6a774fcf322 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js @@ -65,7 +65,9 @@ describe('ReactDOMFizzServer', () => { ); startWriting(); jest.runAllTimers(); - expect(output.result).toBe('
hello world
'); + expect(output.result).toMatchInlineSnapshot( + `"
hello world
"`, + ); }); // @gate experimental @@ -81,8 +83,8 @@ describe('ReactDOMFizzServer', () => { 'test'; // Then React starts writing. startWriting(); - expect(output.result).toBe( - 'test
hello world
', + expect(output.result).toMatchInlineSnapshot( + `"test
hello world
"`, ); }); @@ -129,8 +131,8 @@ describe('ReactDOMFizzServer', () => { 'test'; // Then React starts writing. startWriting(); - expect(output.result).toBe( - 'test
Done
', + expect(output.result).toMatchInlineSnapshot( + `"test
Done
"`, ); }); diff --git a/packages/react-dom/src/server/ReactDOMServerFormatConfig.js b/packages/react-dom/src/server/ReactDOMServerFormatConfig.js index e9d337724e19..c0e55b0a4601 100644 --- a/packages/react-dom/src/server/ReactDOMServerFormatConfig.js +++ b/packages/react-dom/src/server/ReactDOMServerFormatConfig.js @@ -104,6 +104,8 @@ export function pushEmpty( } } +const textSeparator = stringToPrecomputedChunk(''); + export function pushTextInstance( target: Array, text: string, @@ -113,7 +115,12 @@ export function pushTextInstance( if (assignID !== null) { pushDummyNodeWithID(target, responseState, assignID); } - target.push(stringToChunk(encodeHTMLTextNode(text))); + if (text === '') { + // Empty text doesn't have a DOM node representation and the hydration is aware of this. + return; + } + // TODO: Avoid adding a text separator in common cases. + target.push(stringToChunk(encodeHTMLTextNode(text)), textSeparator); } const startTag1 = stringToPrecomputedChunk('<');