Track React-Redux Redundant Re-Renders With “Why Did You Render” Version 3

@welldone-software/why-did-you-render@^3 tracks redundant Hooks re-renders + React-Redux@^7 uses hooks = Great way to track React-Redux redundant re-renders!

Vitali Zaidman
Apr 13, 2019 · 3 min read

Click here to read about Why Did You Render in general.

Since version 7, React-Redux uses React Hooks under the hood to subscribe to Redux state changes in React Context and trigger component re-renders when a state change occurs.

Since version 3, Why Did You Render tracks redundant React Hooks re-renders. You can read more about it here.

This means that the following simple code would result in tracking all React-Redux re-renders where the new props from connect are equal by value but different by reference- redundant re-renders:

whyDidYouRender(React, { include: [/^ConnectFunction$/] })

Here is how a notification of this type looks like:

Image for post
Image for post

Sadly WDYR triggers 3 notifications for every badly handled state change since React Redux uses 3 hooks under the hood.

It is possible to track the React-Redux’s useSelctor hook since version v4 which in a much more convenient way to achieve the same.
Read about version 4 including tracking the “useSelector” hook here

Possible React-Redux Issues

Bad Action Handling

The following simple reducer and action would cause the state to be re-created on every action dispatched:

const initialState = {a: 'a'}function reducer(state = initialState, action){
return action.payload
}
store.dispatch({payload: {a: 'a'}})console.log(store.getState() === initialState)
// false

The reason is that the new state deep equals to the state before the dispatch but it doesn’t equals by reference.

To fix it, make sure you return the previous state if it deep equals to the new one:

const initialState = {a: 'a'}function reducer(state = initialState, action){
if(state.a === action.payload.a){
return state
}

return action.payload
}
store.dispatch({payload: {a: 'a'}})console.log(store.getState() === initialState)
// true

Bad Connection Handling

If the connect function creates an object with new props on it, a re-render would be triggered for every state change in any part of the application:

function SimpleComponent({c}){
console.log('render SimpleComponent!')
return <div>{c.a}</div>
}
const ConnectedComponent = connect(
// Notice how a new "c" is created here on every state change
// Even for state changes that has nothing to do with "a"
// Where state.a === prevState.a
state => ({c: {a: state.a})
)(SimpleComponent)
const initialA = store.getState().a// affects some completely different part of the redux state
store.dispatch({type: 'newX', payload: 'z'})
// "render SimpleComponent!" triggeredconsole.log(store.getState().a === initialA)
// true

To fix it, make sure to not create objects in connect:

function SimpleComponent({a}){
console.log('render SimpleComponent!')
return <div>{a}</div>
}
const ConnectedComponent = connect(
// Notice how the returned "a" prop is always just "a"
state => ({a: state.a})
)(SimpleComponent)
const initialA = store.getState().a// affects some completely different part of the redux state
store.dispatch({type: 'newX', payload: 'z'})
// NOT TRIGGERED: "render SimpleComponent!"console.log(store.getState().a === initialA)
// true

Welldone Software

The leading full-stack consultancy.

Vitali Zaidman

Written by

https://twitter.com/vzaidman ⎝(•ω•)⎠ https://vzaidman.com

Welldone Software

The leading full-stack consultancy. Creating amazing frontends and rock-solid backends using top notch technologies and practices. Visit us at https://welldone.software.

Vitali Zaidman

Written by

https://twitter.com/vzaidman ⎝(•ω•)⎠ https://vzaidman.com

Welldone Software

The leading full-stack consultancy. Creating amazing frontends and rock-solid backends using top notch technologies and practices. Visit us at https://welldone.software.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store