Create a gist now

Instantly share code, notes, and snippets.

@jondlm /README.md
Last active Jan 3, 2018

Embed
What would you like to do?
React shallow render lifecycle breakdown

React introduced shallow rendering in 0.13. This is an excellent feature that I wish was included earlier in React. It aims to solve the problem of unit testing components without going through a real, or jsdom mocked, DOM. I couldn't find any info online about what lifecycle events it actually fires. So I did some testing of my own. To reproduce, put component.js and test.js into a folder and run node test.js.

TLDR; shallow rendering only invokes the following lifecycle hooks (in order):

  1. getDefaultProps
  2. getInitialState
  3. componentWillMount stops here until re-render
  4. componentWillReceiveProps
  5. shouldComponentUpdate
  6. componentWillUpdate
/*eslint node:1 */
'use strict';
var React = require('react');
var Component = React.createClass({
getDefaultProps: function () { console.log('getDefaultProps fired'); return { another: true }; },
getInitialState: function () { console.log('getInitialState fired'); return {}; },
// Life cycle methods
componentWillMount: function () { console.log('componentWillMount fired'); },
componentDidMount: function () { console.log('componentDidMount fired'); },
componentWillReceiveProps: function () { console.log('componentWillReceiveProps fired'); },
shouldComponentUpdate: function () { console.log('shouldComponentUpdate fired'); return true; },
componentWillUpdate: function () { console.log('componentWillUpdate fired'); },
componentDidUpdate: function () { console.log('componentDidUpdate fired'); },
componentWillUnmount: function () { console.log('componentWillUnmount fired'); },
render: function() {
return React.createElement('div');
}
});
module.exports = Component;
/*eslint node:1 */
'use strict';
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var Component = require('./component');
var shallowRenderer = TestUtils.createRenderer();
var props = { something: true };
// Trigger first render
shallowRenderer.render(React.createElement(Component, props));
shallowRenderer.getRenderOutput();
// Update props
props.something = false;
// Trigger a re-render
shallowRenderer.render(React.createElement(Component, props));
shallowRenderer.getRenderOutput();
@sodiumjoe

This comment has been minimized.

Show comment
Hide comment
@sodiumjoe

sodiumjoe Jul 13, 2015

Have you tried this with writing tests? How is it?

sodiumjoe commented Jul 13, 2015

Have you tried this with writing tests? How is it?

@smith-kyle

This comment has been minimized.

Show comment
Hide comment
@smith-kyle

smith-kyle Aug 28, 2015

Thanks for putting this together! This is really something that should be added to the Shallow Rendering portion of the docs.

smith-kyle commented Aug 28, 2015

Thanks for putting this together! This is really something that should be added to the Shallow Rendering portion of the docs.

@collinjackson93

This comment has been minimized.

Show comment
Hide comment
@collinjackson93

collinjackson93 Oct 22, 2015

Why wouldn't they have it fire all the lifecycle methods? Regardless, thank you for experimenting with this, it certainly saved me a lot of frustration debugging. Maybe one day the official documentation will improve.

collinjackson93 commented Oct 22, 2015

Why wouldn't they have it fire all the lifecycle methods? Regardless, thank you for experimenting with this, it certainly saved me a lot of frustration debugging. Maybe one day the official documentation will improve.

@QuantumInformation

This comment has been minimized.

Show comment
Hide comment
@QuantumInformation

QuantumInformation commented Nov 16, 2015

Nice thanks.

@samidarko

This comment has been minimized.

Show comment
Hide comment
@samidarko

samidarko Nov 20, 2015

That's a tricky one. Thanks for the post, so how do we do to test things happening in componentDidMount? Using renderIntoDocument I suppose...

samidarko commented Nov 20, 2015

That's a tricky one. Thanks for the post, so how do we do to test things happening in componentDidMount? Using renderIntoDocument I suppose...

@ronny

This comment has been minimized.

Show comment
Hide comment
@ronny

ronny Nov 27, 2015

componentWillUnmount will be invoked too after shallowRenderer.unmount() is called.

ronny commented Nov 27, 2015

componentWillUnmount will be invoked too after shallowRenderer.unmount() is called.

@ngduc

This comment has been minimized.

Show comment
Hide comment
@ngduc

ngduc Dec 15, 2015

+1 : how to test componentDidMount? Thanks.

ngduc commented Dec 15, 2015

+1 : how to test componentDidMount? Thanks.

@nali

This comment has been minimized.

Show comment
Hide comment
@nali

nali Dec 31, 2015

Thanks so much for this. I'm also trying to test componentDidMount without a deep render and was mystified as to why it doesn't get called.

nali commented Dec 31, 2015

Thanks so much for this. I'm also trying to test componentDidMount without a deep render and was mystified as to why it doesn't get called.

@alopes

This comment has been minimized.

Show comment
Hide comment
@alopes

alopes Jan 11, 2016

+1 componentDidMount

alopes commented Jan 11, 2016

+1 componentDidMount

@gwing33

This comment has been minimized.

Show comment
Hide comment
@gwing33

gwing33 Jan 15, 2016

There use to be a method that grabbed the instance, but in 0.14.6 tag, it doesn't have that method. but if you want to hack it, you can do...

let instance = shallowRenderer._instance._instance;
instance.componentDidMount();

I'd probably avoid shallowRender for this. renderIntoDocument is probably better suited.

gwing33 commented Jan 15, 2016

There use to be a method that grabbed the instance, but in 0.14.6 tag, it doesn't have that method. but if you want to hack it, you can do...

let instance = shallowRenderer._instance._instance;
instance.componentDidMount();

I'd probably avoid shallowRender for this. renderIntoDocument is probably better suited.

@srph

This comment has been minimized.

Show comment
Hide comment
@srph

srph Jan 15, 2016

@gwing33 - I'm not sure if I understand the context; but the behavior of child components can get in the way if you use renderIntoDocument.

srph commented Jan 15, 2016

@gwing33 - I'm not sure if I understand the context; but the behavior of child components can get in the way if you use renderIntoDocument.

@wwalser

This comment has been minimized.

Show comment
Hide comment
@wwalser

wwalser Jun 27, 2016

Following up on @gwing33's comment, I believe getMountedInstance() is the name of the method in question. It exists on all >0.15 branches and master. All lifecycle methods should be available through that for manual triggering.

wwalser commented Jun 27, 2016

Following up on @gwing33's comment, I believe getMountedInstance() is the name of the method in question. It exists on all >0.15 branches and master. All lifecycle methods should be available through that for manual triggering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment