-
Notifications
You must be signed in to change notification settings - Fork 4.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
Data: Avoid responding to componentDidUpdate
in withDispatch
#11866
Conversation
@@ -27,63 +27,57 @@ import { RegistryConsumer } from '../registry-provider'; | |||
* @return {Component} Enhanced component with merged dispatcher props. | |||
*/ | |||
const withDispatch = ( mapDispatchToProps ) => createHigherOrderComponent( | |||
compose( [ | |||
pure, |
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.
Any reason to remove pure?
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.
Any reason to remove pure?
The thought was since we no longer respond to props changes, nor perform any expensive operations in the render, they could just go straight through.
The main downside I might see is if someone had come to rely on withDispatch
for its pure behavior, which is and always would be a fragile dependency.
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 fine with this PR. Ultimately, I think we should try to find a way to measure these PRs somehow, I know it's very difficult to do and I'd appreciate thoughts on that as I want to measure my own performance PRs as well.
This and #11870 could be considered competing approaches. Do you have any preference one way or another? I think this branch is a bigger performance win, but comes at the expense of some developer ergonomics (inability to conditionally return different keys from |
I prefer #11870 because of its simplicity. My hesitation is the performance impact cause I don't know how to measure it. |
There was a typo here. This pull request is a bigger performance win. In case that makes any difference. |
It does, let's go with the most performant one as this is a critical path. |
@aduth Feel free to merge the most performant PR between the two :) |
Going to go with this one. It's a bit more unintuitive in the chance a developer wants to return a separate set of props, but given that the behavior has been largely broken anyways since introduced, and we had no occurrences of it in our code, and it's forward-compatible to reintroduce support, and above all the significant performance win, I think it's a worthwhile compromise. |
Related (alternative to): #11870
Note: The changes are less overwhelming to view when ignoring whitespace changes.
This pull request seeks to explore an optimization to
withDispatch
to avoid running shallow equality comparison on incoming props (viapure
) and in re-assigning "proxy props" at itscomponentDidUpdate
lifecycle. The caveat here is thatmapDispatchToProps
must always return a consistent set of object keys.Implementation notes:
Technically this is very much broken in the current implementation of the component anyways, as the proxy props are only reassigned after the component updates. Thus, the underlying component would not receive the changed prop keys from the new
mapDispatchToProps
return value.The main advantage here is that
mapDispatchToProps
only needs to be called once at component mount and once for each dispatch which occurs. These are significantly fewer occurrences than those under which the props received bywithDispatch
were to change (even whilstpure
).In a separate approach, I may consider to see how to respect changing incoming props while limiting one or both of (a) calls to
mapDispatchToProps
and (b) iterating to create a set ofproxyProps
.Testing instructions:
Ensure tests pass: