Ignore noscript content on the client (#13537)
* Ignore noscript content on the client (#11423) * Fix failing test for ignoring noscript content * Add a ServerIntegration test for noscript
Fredrik Höglund committed
Sep 3, 2018 at 18:17 UTC
0b74e95d7b7fabbd0cf502d0f3254a607ed30478
3 files changed
+50
packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
+19
@@ -36,6 +36,7 @@ const {
36
itThrowsWhenRendering,
37
serverRender,
38
streamRender,
39
+ clientCleanRender,
40
clientRenderOnServerString,
41
} = ReactDOMServerIntegrationUtils(initModules);
42
@@ -576,6 +577,24 @@ describe('ReactDOMServerIntegration', () => {
577
},
578
);
579
580
+ itRenders('a noscript with children', async render => {
581
+ const e = await render(
582
+ <noscript>
583
+ <div>Enable JavaScript to run this app.</div>
584
+ </noscript>,
585
+ );
586
+ if (render === clientCleanRender) {
587
+ // On the client we ignore the contents of a noscript
588
+ expect(e.childNodes.length).toBe(0);
589
+ } else {
590
+ // On the server or when hydrating the content should be correct
591
+ expect(e.childNodes.length).toBe(1);
592
+ expect(e.firstChild.textContent).toBe(
593
+ '<div>Enable JavaScript to run this app.</div>',
594
+ );
595
+ }
596
+ });
597
+
598
describe('newline-eating elements', function() {
599
itRenders(
600
'a newline-eating tag with content not starting with \\n',
packages/react-dom/src/__tests__/ReactServerRenderingHydration.js
+30
@@ -341,4 +341,34 @@ describe('ReactDOMServerHydration', () => {
341
expect(callback).toHaveBeenCalledTimes(0);
342
}
343
});
344
+
345
+ // Regression test for https://github.com/facebook/react/issues/11423
346
+ it('should ignore noscript content on the client and not warn about mismatches', () => {
347
+ const callback = jest.fn();
348
+ const TestComponent = ({onRender}) => {
349
+ onRender();
350
+ return <div>Enable JavaScript to run this app.</div>;
351
+ };
352
+ const markup = (
353
+ <noscript>
354
+ <TestComponent onRender={callback} />
355
+ </noscript>
356
+ );
357
+
358
+ const element = document.createElement('div');
359
+ element.innerHTML = ReactDOMServer.renderToString(markup);
360
+ expect(callback).toHaveBeenCalledTimes(1);
361
+ expect(element.textContent).toBe(
362
+ '<div>Enable JavaScript to run this app.</div>',
363
+ );
364
+
365
+ // On the client we want to keep the existing markup, but not render the
366
+ // actual elements for performance reasons and to avoid for example
367
+ // downloading images. This should also not warn for hydration mismatches.
368
+ ReactDOM.hydrate(markup, element);
369
+ expect(callback).toHaveBeenCalledTimes(1);
370
+ expect(element.textContent).toBe(
371
+ '<div>Enable JavaScript to run this app.</div>',
372
+ );
373
+ });
374
});
packages/react-dom/src/client/ReactDOMHostConfig.js
+1
@@ -247,6 +247,7 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
247
return (
248
type === 'textarea' ||
249
type === 'option' ||
250
+ type === 'noscript' ||
251
typeof props.children === 'string' ||
252
typeof props.children === 'number' ||
253
(typeof props.dangerouslySetInnerHTML === 'object' &&