Skip to content

Instantly share code, notes, and snippets.

@jondlm
Last active January 3, 2018 05:59
  • Star 27 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jondlm/514405bea50fad6fd905 to your computer and use it in GitHub Desktop.
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();
@ngduc
Copy link

ngduc commented Dec 15, 2015

+1 : how to test componentDidMount? Thanks.

@nali
Copy link

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
Copy link

alopes commented Jan 11, 2016

+1 componentDidMount

@gwing33
Copy link

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
Copy link

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
Copy link

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