Skip to content

Commit 69ffbb8

Browse files
committed
Add support for React.pure in ReactDOMServer
1 parent 21a79a1 commit 69ffbb8

2 files changed

Lines changed: 115 additions & 1 deletion

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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+
/* eslint-disable no-func-assign */
11+
12+
'use strict';
13+
14+
const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
15+
16+
let React;
17+
let ReactFeatureFlags;
18+
let ReactDOM;
19+
let ReactDOMServer;
20+
let pure;
21+
let yieldedValues;
22+
let yieldValue;
23+
let clearYields;
24+
25+
function initModules() {
26+
// Reset warning cache.
27+
jest.resetModuleRegistry();
28+
ReactFeatureFlags = require('shared/ReactFeatureFlags');
29+
ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
30+
React = require('react');
31+
ReactDOM = require('react-dom');
32+
ReactDOMServer = require('react-dom/server');
33+
pure = React.pure;
34+
35+
yieldedValues = [];
36+
yieldValue = value => {
37+
yieldedValues.push(value);
38+
};
39+
clearYields = () => {
40+
const ret = yieldedValues;
41+
yieldedValues = [];
42+
return ret;
43+
};
44+
45+
// Make them available to the helpers.
46+
return {
47+
ReactDOM,
48+
ReactDOMServer,
49+
};
50+
}
51+
52+
const {
53+
resetModules,
54+
itRenders,
55+
itThrowsWhenRendering,
56+
serverRender,
57+
} = ReactDOMServerIntegrationUtils(initModules);
58+
59+
describe('ReactDOMServerPure', () => {
60+
beforeEach(() => {
61+
resetModules();
62+
});
63+
64+
function Text({text}) {
65+
yieldValue(text);
66+
return <span>{text}</span>;
67+
}
68+
69+
function Counter({count}) {
70+
return <Text text={'Count: ' + count} />;
71+
}
72+
73+
itRenders('basic render', async render => {
74+
const PureCounter = pure(Counter);
75+
const domNode = await render(<PureCounter count={0} />);
76+
expect(domNode.textContent).toEqual('Count: 0');
77+
});
78+
79+
itRenders('when a ref is passed', async render => {
80+
const RefCounter = (props, ref) => <Counter count={ref.current} />;
81+
const PureRefCounter = pure(RefCounter);
82+
83+
const ref = React.createRef();
84+
ref.current = 0;
85+
const domNode = await render(<PureRefCounter ref={ref} />);
86+
87+
expect(clearYields()).toEqual(['Count: 0']);
88+
});
89+
90+
describe('comparator function', () => {
91+
itRenders('basic usage', async render => {
92+
const PureCounter = pure(Counter, (oldProps, newProps) => false);
93+
const domNode = await render(<PureCounter count={0} />);
94+
expect(clearYields()).toEqual(['Count: 0']);
95+
});
96+
97+
itRenders(
98+
'comparator functions are not invoked on the server',
99+
async render => {
100+
const PureCounter = pure(Counter, (oldProps, newProps) => {
101+
yieldValue(
102+
`Old count: ${oldProps.count}, New count: ${newProps.count}`,
103+
);
104+
return oldProps.count === newProps.count;
105+
});
106+
107+
const domNode = await render(<PureCounter count={0} />);
108+
expect(clearYields()).toEqual(['Count: 0']);
109+
},
110+
);
111+
});
112+
});

packages/react-dom/src/server/ReactPartialRenderer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
REACT_PROFILER_TYPE,
3939
REACT_PROVIDER_TYPE,
4040
REACT_CONTEXT_TYPE,
41+
REACT_PURE_TYPE,
4142
} from 'shared/ReactSymbols';
4243

4344
import {
@@ -945,7 +946,8 @@ class ReactDOMServerRenderer {
945946
}
946947
if (typeof elementType === 'object' && elementType !== null) {
947948
switch (elementType.$$typeof) {
948-
case REACT_FORWARD_REF_TYPE: {
949+
case REACT_FORWARD_REF_TYPE:
950+
case REACT_PURE_TYPE: {
949951
const element: ReactElement = ((nextChild: any): ReactElement);
950952
const nextChildren = toArray(
951953
elementType.render(element.props, element.ref),

0 commit comments

Comments
 (0)