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.

Dropdown: componentWillReceiveProps performs deep equal on React component

See original GitHub issue

Bug Report

Steps

Create a Dropdown with content, for example like in https://react.semantic-ui.com/modules/dropdown#usage-item-content. The content must contain a React component, for example:

content: <Header icon='desktop' content='Desktop' subheader='The largest size' />,

Expected Result

App should run normally, display the header, update the dropdown as needed, etc.

Actual Result

When Dropdown’s componentWillReceiveProps runs, the app freezes for a minute or more. The issue is in line https://github.com/Semantic-Org/Semantic-UI-React/blob/972b999b7e9f85fb6722a1749c4c121c03e5613d/src/modules/Dropdown/Dropdown.js#L426. The deep equals recurses into the Header object, which has cyclical references (for example nextProps.options[0].content._owner === nextProps.options[0].content._owner.return.child) as well as recursive references through the entire app treee (like _owner._debugOwner._debugOwner._debugOwner... all the way to the root) and thus the app hangs.

The code in question came in via https://github.com/Semantic-Org/Semantic-UI-React/pull/2252, where performance risks of a deep equal were already mentioned.

Version

0.82.0

Testcase

The bug won’t reproduce in a small sample app, because in that case lodash.isEqual can traverse the entire app quickly. You’ll need a fairly large app to get a freeze of several seconds and it gets worse in debug mode, because then React components have the _debugOwner property set, which can be followed all the way to the root component.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
FabianFrankcommented, Jul 22, 2018

@levithomason I agree, a falsely skipped property is worse than recursing into one too many. I was thinking of a blacklist approach, i.e. use a heuristic to determine if the current object is a React component (i.e. it has a render function, maybe some other properties or functions) and then blacklist certain properties (maybe only _debugOwner if things are speedy after that) and then see how far that gets us. If people are generally ok with such an approach, I’ll try to find time this week to make a PR. Let me know!

0reactions
levithomasoncommented, Jul 22, 2018

We just need to be sure that changes to nested properties within options will be considered a change and update the component.

We could add our own lib util for doing equality checks. It could ignore private React properties. Thoughts?

Read more comments on GitHub >

github_iconTop Results From Across the Web

React.Component
React lets you define components as classes or functions. ... We do not recommend doing deep equality checks or using JSON.stringify() in ...
Read more >
Comparing and Modifying Objects in React | Rapid7 Blog
Without a separate library, how does one easily modify and compare javascript objects by some set of their inner fields in purely React?...
Read more >
Using React componentDidUpdate() — React Hooks
Every time the “Resize” button is clicked and the setState function is called, the componentDidUpdate function starts running, and the component ...
Read more >
setState() inside of componentDidUpdate() - Stack Overflow
let SearchDropdown = React.createClass({ getInitialState() { return { top: false }; }, componentDidUpdate( ...
Read more >
Use React.memo() wisely
React.memo() increases the performance of functional components by ... let's manually calculate if Movie component props are equal:.
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