Prevent Unnecessary Rerenders of Compound Components using React Context

Share this video with your friends

Send Tweet

Due to the way that React Context Providers work, our current implementation re-renders all our compound component consumers with every render of the <Toggle /> which could lead to unnecessary re-renders. Let's fix that by ensuring that the value prop we pass to the <ToggleContext.Provider /> is only changed when the state changes.

Matt Greer
Matt Greer
~ 6 years ago

Is this correct? I don't believe context providers check to see if the value prop is a new reference. I hacked at the 03.extra-2 exercise in the codebox and despite Toggle.Provider's value object not changing, all the children still render: https://codesandbox.io/s/0o1vr39yow (check the console)

Kent C. Dodds
Kent C. Dodds(instructor)
~ 6 years ago

Hey Matt, Honestly, it's a pretty edge case and perhaps I shouldn't have included it in the video. The only time this will make a difference is if the consumers are below a PureComponent or shouldComponentUpdate that returns false: https://codesandbox.io/s/50y9y2z0x4?module=%2Fsrc%2Fexercises-final%2F03.extra-2.js

Pretty edge case-y. I probably shouldn't even bother teaching it. But now you know!

Christian
Christian
~ 6 years ago

Hi Kent, not so much edgy, I guess, considering that all the Redux connected components are 'pure' by default. So thanks for showing this. :)

Babs Craig
Babs Craig
~ 6 years ago

Hi Kent, what happens in a scenario where one of the values being passed to ToggleContext.Provider is being set by props? So for instance if we were passing <Ticker someProp={withSomeData} /> and we want to pass someProp down through the Provider inside of the Ticker component? What would be the best way to accomplish this? Thanks!

Kent C. Dodds
Kent C. Dodds(instructor)
~ 6 years ago

You could just forward it along. The passer of that prop would be responsible for this optimization. This is a bit of an edge case though, so you're probably find to just go with whatever feels easiest, then come back and optimize it if it feels slow.