-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
forwardRef() components should not re-render on deep setState() #12690
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also compare
workInProgress.ref
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With what?
(Sorry if I'm being dense)
Also, is it possible for a deep update to influence the value of a ref above it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but it seems conceivable that a
ref
could be the only changed "prop" (if it's an inline arrow function for a non-PureComponent
) and we might bail out when we shouldn't here?Although in that case it probably wouldn't matter anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm... maybe
Foo
gets new properties that causes it to recreate the ref, but only a filtered set of those props are passed through to theForwardRef
component, so from it's POV nothing has changed?Maybe this is too contrived.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, that sounds potentially plausible. If you find any free time to hack on this I'd appreciate a test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe this is too contrived to be a real concern.
Ref callbacks would be re-invoked if the underlying instance/ref changed. If the ref callback itself changed, most likely this just means it's an arrow functions and has an identical implementation.
createRef
would be more problematic, but it is only expected to be created once in the first place, so in practice shouldn't be a problem.Maybe we should just add an inline comment saying this is technically possible but probably not a concern in practice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think we can rely on something like this. Otherwise we might as well never update refs.
We handled this correctly so far so I don’t think we should regress in this particular case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to write a contrived test to catch the case we're talking about, and it looks like I was mistaken to begin with. Even if props are shallowly equal, the
memoizedProps
andpendingProps
objects themselves won't be equal- so we won't bail out- which side steps the issue I mentioned.Sorry for the dead end. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We chatted a bit with @acdlite and he proposed to check against
current.ref
. Seems like it wouldn’t hurt but I’ll think about it more tomorrow.