@samitouri / QOS-React / commits / 18a81a4445

Fix server render strict mode (#12170)

* Fix server render with <StrictMode> component * add failed tests for <StrictMode> with server rendering

C. T. Lin committed Feb 7, 2018 at 15:51 UTC 18a81a4445f3a7e0a38f9840b472f1ed63a99e9c
3 files changed +109 -1
packages/react-dom/src/__tests__/ReactDOMServerIntegrationFragment-test.js
+1 -1
@@ -99,7 +99,7 @@ describe('ReactDOMServerIntegration', () => {
99 expect(parent.childNodes[2].tagName).toBe('P');
100 });
101
102 - itRenders('an empty framgent', async render => {
102 + itRenders('an empty fragment', async render => {
103 expect(await render(<React.Fragment />)).toBe(null);
104 });
105 });
packages/react-dom/src/__tests__/ReactDOMServerIntegrationStrictMode-test.js new
+106
@@ -0,0 +1,106 @@
1 +/**
2 + * Copyright (c) 2013-present, Facebook, Inc.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @emails react-core
8 + */
9 +
10 +'use strict';
11 +
12 +const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
13 +
14 +let React;
15 +let ReactDOM;
16 +let ReactDOMServer;
17 +
18 +function initModules() {
19 + // Reset warning cache.
20 + jest.resetModuleRegistry();
21 + React = require('react');
22 + ReactDOM = require('react-dom');
23 + ReactDOMServer = require('react-dom/server');
24 +
25 + // Make them available to the helpers.
26 + return {
27 + ReactDOM,
28 + ReactDOMServer,
29 + };
30 +}
31 +
32 +const {resetModules, itRenders} = ReactDOMServerIntegrationUtils(initModules);
33 +
34 +describe('ReactDOMServerIntegration', () => {
35 + beforeEach(() => {
36 + resetModules();
37 + });
38 +
39 + describe('React.StrictMode', () => {
40 + itRenders('a strict mode with one child', async render => {
41 + let e = await render(
42 + <React.StrictMode>
43 + <div>text1</div>
44 + </React.StrictMode>,
45 + );
46 + let parent = e.parentNode;
47 + expect(parent.childNodes[0].tagName).toBe('DIV');
48 + });
49 +
50 + itRenders('a strict mode with several children', async render => {
51 + let Header = props => {
52 + return <p>header</p>;
53 + };
54 + let Footer = props => {
55 + return (
56 + <React.StrictMode>
57 + <h2>footer</h2>
58 + <h3>about</h3>
59 + </React.StrictMode>
60 + );
61 + };
62 + let e = await render(
63 + <React.StrictMode>
64 + <div>text1</div>
65 + <span>text2</span>
66 + <Header />
67 + <Footer />
68 + </React.StrictMode>,
69 + );
70 + let parent = e.parentNode;
71 + expect(parent.childNodes[0].tagName).toBe('DIV');
72 + expect(parent.childNodes[1].tagName).toBe('SPAN');
73 + expect(parent.childNodes[2].tagName).toBe('P');
74 + expect(parent.childNodes[3].tagName).toBe('H2');
75 + expect(parent.childNodes[4].tagName).toBe('H3');
76 + });
77 +
78 + itRenders('a nested strict mode', async render => {
79 + let e = await render(
80 + <React.StrictMode>
81 + <React.StrictMode>
82 + <div>text1</div>
83 + </React.StrictMode>
84 + <span>text2</span>
85 + <React.StrictMode>
86 + <React.StrictMode>
87 + <React.StrictMode>
88 + {null}
89 + <p />
90 + </React.StrictMode>
91 + {false}
92 + </React.StrictMode>
93 + </React.StrictMode>
94 + </React.StrictMode>,
95 + );
96 + let parent = e.parentNode;
97 + expect(parent.childNodes[0].tagName).toBe('DIV');
98 + expect(parent.childNodes[1].tagName).toBe('SPAN');
99 + expect(parent.childNodes[2].tagName).toBe('P');
100 + });
101 +
102 + itRenders('an empty strict mode', async render => {
103 + expect(await render(<React.StrictMode />)).toBe(null);
104 + });
105 + });
106 +});
packages/react-dom/src/server/ReactPartialRenderer.js
+2
@@ -28,6 +28,7 @@ import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState';
28 import {warnAboutDeprecatedLifecycles} from 'shared/ReactFeatureFlags';
29 import {
30 REACT_FRAGMENT_TYPE,
31 + REACT_STRICT_MODE_TYPE,
32 REACT_CALL_TYPE,
33 REACT_RETURN_TYPE,
34 REACT_PORTAL_TYPE,
@@ -814,6 +815,7 @@ class ReactDOMServerRenderer {
815 }
816
817 switch (elementType) {
818 + case REACT_STRICT_MODE_TYPE:
819 case REACT_FRAGMENT_TYPE: {
820 const nextChildren = toArray(
821 ((nextChild: any): ReactElement).props.children,