Skip to content

Commit 5d51854

Browse files
committed
Added static getDerivedStateFromProps to ReactPartialRenderer
Also added a new set of tests focused on server side lifecycle hooks.
1 parent 8679926 commit 5d51854

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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 ReactDOMServer;
16+
17+
function initModules() {
18+
// Reset warning cache.
19+
jest.resetModuleRegistry();
20+
React = require('react');
21+
ReactDOMServer = require('react-dom/server');
22+
23+
// Make them available to the helpers.
24+
return {
25+
ReactDOMServer,
26+
};
27+
}
28+
29+
const {resetModules} = ReactDOMServerIntegrationUtils(initModules);
30+
31+
describe('ReactDOMServerLifecycles', () => {
32+
beforeEach(() => {
33+
resetModules();
34+
});
35+
36+
it('should invoke the correct lifecycle hooks', () => {
37+
const log = [];
38+
39+
class Outer extends React.Component {
40+
unsafe_componentWillMount() {
41+
log.push('outer componentWillMount');
42+
}
43+
render() {
44+
log.push('outer render');
45+
return <Inner />;
46+
}
47+
}
48+
49+
class Inner extends React.Component {
50+
unsafe_componentWillMount() {
51+
log.push('inner componentWillMount');
52+
}
53+
render() {
54+
log.push('inner render');
55+
return null;
56+
}
57+
}
58+
59+
ReactDOMServer.renderToString(<Outer />);
60+
expect(log).toEqual([
61+
'outer componentWillMount',
62+
'outer render',
63+
'inner componentWillMount',
64+
'inner render',
65+
]);
66+
});
67+
68+
it('should warn about deprecated lifecycle hooks', () => {
69+
class Component extends React.Component {
70+
componentWillMount() {}
71+
render() {
72+
return null;
73+
}
74+
}
75+
76+
expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
77+
'Warning: Component: componentWillMount() is deprecated and will be removed ' +
78+
'in the next major version. Please use unsafe_componentWillMount() instead.',
79+
);
80+
});
81+
82+
it('should update instance.state with value returned from getDerivedStateFromProps', () => {
83+
class Grandparent extends React.Component {
84+
state = {
85+
foo: 'foo',
86+
};
87+
render() {
88+
return (
89+
<div>
90+
{`Grandparent: ${this.state.foo}`}
91+
<Parent />
92+
</div>
93+
);
94+
}
95+
}
96+
97+
class Parent extends React.Component {
98+
state = {
99+
bar: 'bar',
100+
baz: 'baz',
101+
};
102+
static getDerivedStateFromProps(props, prevState) {
103+
return {
104+
bar: `not ${prevState.bar}`,
105+
};
106+
}
107+
render() {
108+
return (
109+
<div>
110+
{`Parent: ${this.state.bar}, ${this.state.baz}`}
111+
<Child />;
112+
</div>
113+
);
114+
}
115+
}
116+
117+
class Child extends React.Component {
118+
static getDerivedStateFromProps() {
119+
return {
120+
qux: 'qux',
121+
};
122+
}
123+
render() {
124+
return `Child: ${this.state.qux}`;
125+
}
126+
}
127+
128+
const markup = ReactDOMServer.renderToString(<Grandparent />);
129+
expect(markup).toContain('Grandparent: foo');
130+
expect(markup).toContain('Parent: not bar, baz');
131+
expect(markup).toContain('Child: qux');
132+
});
133+
});

Diff for: packages/react-dom/src/server/ReactPartialRenderer.js

+11
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,17 @@ function resolve(
421421

422422
if (shouldConstruct(Component)) {
423423
inst = new Component(element.props, publicContext, updater);
424+
425+
if (typeof Component.getDerivedStateFromProps === 'function') {
426+
partialState = Component.getDerivedStateFromProps(
427+
element.props,
428+
inst.state,
429+
);
430+
431+
if (partialState) {
432+
inst.state = Object.assign({}, inst.state, partialState);
433+
}
434+
}
424435
} else {
425436
if (__DEV__) {
426437
if (

0 commit comments

Comments
 (0)