-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Element: Provide createHigherOrderComponent helper #5728
Conversation
element/index.js
Outdated
return ( OriginalComponent ) => { | ||
const EnhancedComponent = mapComponentToEnhancedComponent( OriginalComponent ); | ||
const { displayName = OriginalComponent.name || 'Component' } = OriginalComponent; | ||
EnhancedComponent.displayName = `${ modifierName }(${ displayName })`; |
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 had upperFirst
& camelCase
on top of the modifier name to make sure it always looks like the name of the component. We may enforce it at the review time. Your call.
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.
This is what we exactly what we discussed some time ago. I like this new HOC helper. We should refactor also all the existing occurrences and deprecate getWrapperDisplayName
. We should also adjust the existing test for getWrapperDisplayName
to work with the HOC or provide something similar. I can help with that tomorrow.
Yes, just wanted to say that I like how those HOCs evolve and make adding new functionalities easy to compose 💯 |
@aduth - I added the following changes with d9bbcf9:
I tried to make this PR small so in some cases we might perform more refactorings, but I wanted to avoid too much noise to make the review process easier. |
Something to think a bit more. I noticed that in many cases we define the same name for export const withAlign = createHigherOrderComponent( ( BlockListBlock ) => {
return ( props ) => {
...
return <BlockListBlock { ...props } wrapperProps={ wrapperProps } />;
};
}, 'withAlign' ); I'm not sure if it is a good idea, but we might want to make the |
return ( OriginalComponent ) => { | ||
const EnhancedComponent = mapComponentToEnhancedComponent( OriginalComponent ); | ||
const { displayName = OriginalComponent.name || 'Component' } = OriginalComponent; | ||
EnhancedComponent.displayName = `${ upperFirst( camelCase( modifierName ) ) }(${ displayName })`; |
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 replicated the old behavior upperFirst( camelCase( modifierName ) )
when porting old tests - feel free to update if you think it's not necessary.
lib/client-assets.php
Outdated
@@ -141,7 +141,7 @@ function gutenberg_register_scripts_and_styles() { | |||
wp_register_script( | |||
'wp-element', | |||
gutenberg_url( 'element/build/index.js' ), | |||
array( 'react', 'react-dom', 'react-dom-server' ), | |||
array( 'react', 'react-dom', 'react-dom-server', 'wp-utils' ), |
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 hope it's temporary until we remove deprecated function :)
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.
Pending my observations, LGTM
return WrappedComponent; | ||
}; | ||
}; | ||
} ); |
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.
Missing 'withState'
as modifierName
.
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.
(amended & pushed)
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.
Thanks 👍
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 see amend?
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.
Oh. Maybe it got nuked in a subsequent rebase, @gziolo?
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.
Yes, I did something wrong :(
Do you have this branch locally with your commit?
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.
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.
Fixed with 66b2268, thanks!
* | ||
* @return {WPComponent} Component class with generated display name assigned. | ||
*/ | ||
export function createHigherOrderComponent( mapComponentToEnhancedComponent, modifierName ) { |
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.
Since we don't attempt to infer modiferName
, should there be a warning if the argument is missing?
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 would leave it for reviewers for the time being. It seems to be a really great strategy 😃
In the next iteration, I would prefer to introduce the attempt infer this name and warn when it fails.
Perhaps. I expect this wouldn't work so well for minified code (related: Automattic/wp-calypso#18650 ). Whether we care about this is another question, as we're not really using the name in runtime environments except maybe React DevTools. |
You can instrument uglify to preserve function names, but still it might not always work. It seems to be okay as it is in that context. |
Context: #5206 (comment)
This pull request seeks to experiment with an alternative to
@wordpress/element
'sgetWrapperDisplayName
function which is used to generate a display name for higher-order components. The use of this function is not always obvious, and can overcomplicate otherwise simple higher-order components by requiring the separate assignment of a class/function before then assigningdisplayName
. The idea here is to eliminate consideration of thedisplayName
with a generic helper for creating higher-order components, handling the assignment of the generated display name within the helper itself.Implementation notes:
The code functionally works, though there are many other higher-order components we'd want to port if wanting to proceed, plus deprecating
getWrapperDisplayName
, or alternatively discouraging its use and leveraging it as the internal behavior ofcreateHigherOrderComponent
.