question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Update shouldComponentUpdate docs with advice about closures

See original GitHub issue

Do 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:closed
  • Created 6 years ago
  • Comments:49 (21 by maintainers)

github_iconTop GitHub Comments

22reactions
gaearoncommented, Feb 9, 2018
screen shot 2018-02-09 at 7 02 46 pm

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 return true when this.props.children !== prevProps.children. In this example, Indirection “swallowed” the new closure.

7reactions
acdlitecommented, Feb 9, 2018

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 the topController.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:

  • Add additional documentation for shouldComponentUpdate with advice to never treat two closures or two children props as equal unless they are referentially identical, since it’s impossible to know what values they close over.
  • In the documentation for the new context API, when advertising its ability to bypass shouldComponentUpdate bailouts, don’t mislead people into thinking that it can reach into JavaScript closures and swap out those values, too 😆
Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found