React.PureComponent doesn't work when the Component has children?
What happen here is you're actually calling ReactDOM.render()
, Page (or App, I suppose you have a typo here) component is gonna trigger its render()
function regardless of using Component
or PureComponent
.
The way PureComponent can help to reduce unnecessary rendering is when there is a prop change, PureComponent will do a shallow comparison on this.props
and nextProps
to determine if this PureComponent needs to call render()
.
I just made this example for you:
class App extends React.PureComponent {
state = {value: 0}
componentDidMount() {
setInterval(() => {
this.setState({value: Math.random()})
}, 1000)
}
render() {
return (
<div>
<PureChild value="fixed value"/>
<ImpureChild value="fixed value"/>
</div>
)
}
}
class PureChild extends React.PureComponent {
render() {
console.log('rendering PureChild')
return <div>{this.props.value}</div>
}
}
class ImpureChild extends React.Component {
render() {
console.log('rendering ImpureChild')
return <div>{this.props.value}</div>
}
}
Pay attention to this few things:
- Both children are receiving a fixed props ("fixed value" string)
- Every 1 second, the parent
<App />
changevalue
state, thus it re-renders, causing all its children to re-render as well. - But since
<PureChild />
is a PureComponent, it does a shallow comparison on its old props and incoming new props, and notices both props are"fixed value"
, and therefore it doesn't trigger render!
If you run this code and open up console, you'll see only 'rendering ImpureChild' every 1s, but 'rendering PureChild' will only appear once.
console.log(<div /> === <div />) // false
On every rerender of <App />
, a new React Element was created by React.createElement(div, null)
, thus this.props.children
will be different from nextProps.children
though they look the same in JSX.
In fact, the real problem is that the reference(otherwise value if is primitive type) of props.children
changes every time the parent re-renders and React.PureComponent compares props by reference embracing immutability.