Skip to content

Commit 28bb317

Browse files
johnhaitasdevelopit
authored andcommitted
Adds support for getDerivedStateFromProps (#63)
* Adds support for `getDerivedStateFromProps` * Adding tests to verify that `getDerivedStateFromProps` is correctly called and that it takes precedence over `componentWillMount` * changing `c.constructor` reference to `nodeName` to save a few bytes and a lookup per #63 (comment)
1 parent 5cb646a commit 28bb317

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ function renderToString(vnode, context, opts, inner, isSvgMode) {
7373
c._disable = c.__x = true;
7474
c.props = props;
7575
c.context = context;
76-
if (c.componentWillMount) c.componentWillMount();
76+
if (nodeName.getDerivedStateFromProps) c.state = assign(assign({}, c.state), nodeName.getDerivedStateFromProps(c.props, c.state));
77+
else if (c.componentWillMount) c.componentWillMount();
7778
rendered = c.render(c.props, c.state, c.context);
7879

7980
if (c.getChildContext) {

test/render.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,23 @@ describe('render', () => {
310310
expect(render(<Test foo={undefined} bar="b" />), 'overridden').to.equal('<div foo="default foo" bar="b"></div>');
311311
});
312312

313+
it('should invoke getDerivedStateFromProps', () => {
314+
class Test extends Component {
315+
static getDerivedStateFromProps() {}
316+
render(props) {
317+
return <div {...props} />;
318+
}
319+
}
320+
spy(Test.prototype.constructor, 'getDerivedStateFromProps');
321+
spy(Test.prototype, 'render');
322+
323+
render(<Test />);
324+
325+
expect(Test.prototype.constructor.getDerivedStateFromProps)
326+
.to.have.been.calledOnce
327+
.and.to.have.been.calledBefore(Test.prototype.render);
328+
});
329+
313330
it('should invoke componentWillMount', () => {
314331
class Test extends Component {
315332
componentWillMount() {}
@@ -327,6 +344,27 @@ describe('render', () => {
327344
.and.to.have.been.calledBefore(Test.prototype.render);
328345
});
329346

347+
it('should invoke getDerivedStateFromProps rather than componentWillMount', () => {
348+
class Test extends Component {
349+
static getDerivedStateFromProps() {}
350+
componentWillMount() {}
351+
render(props) {
352+
return <div {...props} />;
353+
}
354+
}
355+
spy(Test.prototype.constructor, 'getDerivedStateFromProps');
356+
spy(Test.prototype, 'componentWillMount');
357+
spy(Test.prototype, 'render');
358+
359+
render(<Test />);
360+
361+
expect(Test.prototype.constructor.getDerivedStateFromProps)
362+
.to.have.been.calledOnce
363+
.and.to.have.been.calledBefore(Test.prototype.render);
364+
expect(Test.prototype.componentWillMount)
365+
.to.not.have.been.called;
366+
});
367+
330368
it('should pass context to grandchildren', () => {
331369
const CONTEXT = { a: 'a' };
332370
const PROPS = { b: 'b' };

0 commit comments

Comments
 (0)