Update shouldComponentUpdate docs with advice about closures
See original GitHub issueDo you want to request a feature or report a bug?
Possible bug depending on my understanding of the new context feature.
What is the current behavior?
The presence of an <Indirection>
component with shouldComponentUpdate:false
is blocking updates to context consumers below it after the first click of “Toggle Top Data”: https://codesandbox.io/s/v87rp187r7
What is the expected behavior?
For consumers below a shouldComponentUpdate component to continue updating after the first “Toggle Top Data” click.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 16.3.0-alpha.0
Issue Analytics
- State:
- Created 6 years ago
- Comments:49 (21 by maintainers)
Top Results From Across the Web
дэн on Twitter: "If you use render props, make sure ...
If you use render props, make sure shouldComponentUpdate() in your ... Update shouldComponentUpdate docs with advice about closures · Issue ...
Read more >When shouldComponentUpdate / render is called for child ...
shouldComponentUpdate is just called from setState and forces render when returns true (default behaviour) - and updating DOM when different ...
Read more >React shouldComponentUpdate() | How does it Work in React?
This function takes two arguments one is nextprops and another is nextState.By comparing we can decide if it is important to render the...
Read more >Hooks FAQ - React
Hooks FAQ · Can I skip an effect on updates? · Is it safe to omit functions from the list of dependencies? ·...
Read more >Use Closure to store variables to avoid re-render in ReactJS
We can overwrite shouldComponentUpdate in the React.Component. The component won't render if shouldComponentUpdate returns false in this function. source: ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
To anyone reading this later, to avoid this problem always make sure that you either don’t write
shouldComponentUpdate
by hand, or, if you do, that you returntrue
whenthis.props.children !== prevProps.children
. In this example,Indirection
“swallowed” the new closure.There are a few things going on here. One is that closures are confusing. It’s really easy to accidentally depend on values from an outer scope without realizing it. @gaearon is right that render props, because they rely on closures, can exacerbate this confusion.
But in my view the core problem with all these examples is that
shouldComponentUpdate
always returns false. The solution is… not to do that 😄 (So it’s worth pointing out that you could have this same bug with an HOC or with a normal component, too.)By returning return false from Indirection’s
shouldComponentUpdate
, you’re signaling to React that the children are the same. So, it never re-renders the children, so the click event handler never gets updated with the new closure values, so thetopController.data
is stale the next time you click it.The unit tests for context happen always return false in
shouldComponentUpdate
in a few places, but that’s my bad. I should have chosen a more realistic scenario. You should never do that unless the children are completely static.I believe the actionable items for React here are:
shouldComponentUpdate
with advice to never treat two closures or twochildren
props as equal unless they are referentially identical, since it’s impossible to know what values they close over.shouldComponentUpdate
bailouts, don’t mislead people into thinking that it can reach into JavaScript closures and swap out those values, too 😆