Trace why a React component is re-rendering
If you want a short snippet without any external dependencies I find this useful
componentDidUpdate(prevProps, prevState) { Object.entries(this.props).forEach(([key, val]) => prevProps[key] !== val && console.log(`Prop '${key}' changed`) ); if (this.state) { Object.entries(this.state).forEach(([key, val]) => prevState[key] !== val && console.log(`State '${key}' changed`) ); }}
Here is a small hook I use to trace updates to function components
function useTraceUpdate(props) { const prev = useRef(props); useEffect(() => { const changedProps = Object.entries(props).reduce((ps, [k, v]) => { if (prev.current[k] !== v) { ps[k] = [prev.current[k], v]; } return ps; }, {}); if (Object.keys(changedProps).length > 0) { console.log('Changed props:', changedProps); } prev.current = props; });}// Usagefunction MyComponent(props) { useTraceUpdate(props); return <div>{props.children}</div>;}
Here are some instances that a React component will re-render.
- Parent component rerender
- Calling
this.setState()
within the component. This will trigger the following component lifecycle methodsshouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
- Changes in component's
props
. This will triggercomponentWillReceiveProps
>shouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
(connect
method ofreact-redux
trigger this when there are applicable changes in the Redux store) - calling
this.forceUpdate
which is similar tothis.setState
You can minimize your component's rerender by implementing a check inside your shouldComponentUpdate
and returning false
if it doesn't need to.
Another way is to use React.PureComponent
or stateless components. Pure and stateless components only re-render when there are changes to it's props.
You can check the reason for a component's (re)render with the React Devtools profiler tool. No changing of code necessary. See the react team's blog post Introducing the React Profiler.
First, go to settings cog > profiler, and select "Record why each component rendered"