"Shawn, PureRenderMixin
is an add-on that can be used in place of shouldComponentUpdate
. Under the hood, it uses shouldComponentUpdate
and compares the current props and state with the next props and states. Let's try it in our code. First, we need to install the add-on, of course." said Mike.
$ npm install react-addons-pure-render-mixin // src/Header.js import React from 'react'; import PureRenderMixin from 'react-addons-pure-render-mixin'; export default React.createClass({ mixins: [PureRenderMixin], .. .. }) // src/Form.js import React from 'react'; import PureRenderMixin from 'react-addons-pure-render-mixin'; export default React.createClass({ mixins: [PureRenderMixin], .. .. } })
"Shawn, let's see the wasted time now that we have used PureRenderMixin
." said Mike.
"Oh, it got worse. The PureRenderMixin
function added the time wasted in re-rendering Form
and Header
components back. What is going on, Mike?" Shawn asked.
"Calm down! I am going to explain why this happened. The PureRenderMixin
compares the current props and state with the next props and state, but it does shallow comparison. Therefore, if we are passing the state or props that contain objects and arrays, then the shallow comparison will not return true even if they both have the same content." Mike explained.
"However, where are we passing any complex objects or arrays to the Header
and Form
components? We are just passing the book data such as the name of author, edition count, and so on. We are not passing anything to Header
, how does PureRenderMixin
fail?" Shawn asked.
"You are forgetting style prop passed to Header
and Form
from the App
component." informed Mike.
// src/App.js render() { let style = {paddingTop: '5%'}; return ( <div className='container'> <Header style={style}></Header> <Form style={style} performSearch={this._performSearch}> </Form> .. .. </div> )}
"Each time App
gets re-rendered, a new object for style is created and sent to Header
and Form
in props."
The PureRenderMixin
internally implements shouldComponentUpdate
, as follows:
var ReactComponentWithPureRenderMixin = { shouldComponentUpdate: function(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); }, };
The shallowCompare
function is also an add-on provided by React that is a helper function to compare the current state and props with the next state and props. It basically achieves the same thing as PureRenderMixin
, but as it is a function, it can be used directly instead of using PureRenderMixin
. It is especially needed when we are using ES6 classes with React." Mike explained.
"Mike, so the shallow comparison is the reason why PureRenderMixin
is failing to detect that there is no change in the next props?" Shawn asked.
"Yes. The shallowCompare
just iterates over the keys of objects that are being compared and returns false when the value of the key in each object is not strictly equal. Therefore, if we pass simple props, as follows, then shallowCompare
will correctly determine that re-rendering is not required:"
// shallowCompare will detect correctly that props are not changed. { author_name: "Dan Brown", edition_count: "20", title: "Angels and Demons" }
"However, it will fail immediately with a prop that is an object or array."
{ author_name: "Dan Brown", edition_count: "20", title: "Angels and Demons", style: { paddingTop: '%5' } }
"Though PureRenderMixin
saves us a few lines of code, it may not work all the time as we expect it to work. Especially when we have mutable state, objects, or arrays in props." said Mike.
"Got it. So we can write our own shouldComponentUpdate
function when we have nested state or props right?", Shawn asked.
"Yes. PureRenderMixin
and shallowCompare
is good for simple components with simple props and states but we should take care when we are using it." Mike.
Using mixins is discouraged in React world for various reasons. Checkout alternative approaches for PureRenderMixin
pattern here - https://github.com/gaearon/react-pure-render.