-
Notifications
You must be signed in to change notification settings - Fork 68
Improve forwardRef documentation, add displayName argument #251
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
Improve forwardRef documentation, add displayName argument #251
Conversation
5c19d8d
to
722ee9e
Compare
+ And update forwardRef documentation to recommend its use
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 looks awesome! Just a thought and nit, but them I'm +1!
+ And use that configurability within `forwardRefToJs` to ensure that the HOC created by forwardRef gets the events converted to Dart SyntheticEvents, while keeping the events passed to the wrapped JS component - unconverted (plain JS)
…d less error prone
lib/react_client/react_interop.dart
Outdated
/// print(textFieldInputNodeRef.current.value); | ||
/// } | ||
/// ``` | ||
ReactJsComponentFactoryProxy forwardRefToJs( |
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.
Taking a fresh look at what this functionality provides, I think this name is misleading, since it doesn't really provide similar functionality to forwardRef.
What about something like withJsRefsConverted
? Also, additionalRefPropKeys
should probably be renamed to not have additional
, since this function doesn't really do anything without them
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 confused what you mean by "doesn't really provide similar functionality to forwardRef".
This function returns the return value of a call to forwardRef
.
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.
Right, but it doesn't allow you to forward a ref onto a different component/prop. It's really just a HOC that's using forwardRef
.
For example, the last snippet in this section: https://reactjs.org/docs/forwarding-refs.html#forwarding-refs-in-higher-order-components
function logProps(Component) { class LogProps extends React.Component { componentDidUpdate(prevProps) { console.log('old props:', prevProps); console.log('new props:', this.props); } render() { const {forwardedRef, ...rest} = this.props; // Assign the custom prop "forwardedRef" as a ref return <Component ref={forwardedRef} {...rest} />; } } // Note the second param "ref" provided by React.forwardRef. // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef" // And it can then be attached to the Component. return React.forwardRef((props, ref) => { return <LogProps {...props} forwardedRef={ref} />; }); }
logProps
isn't logPropsForwardRef
, it just uses it so that the HOC passes the ref through.
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.
@greglittlefield-wf I disagree that from an API clarity standpoint - withJsRefsConverted
is more clear about the purpose of the function.
The purpose of the function is so that refs get forwarded. All the HOC wrapping is semantics, IMO. The function does more than just convert refs... it also forwards them to the JS component.
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.
Okay, so taking a step back...
At this point, this function is just a wrapper around ReactJsComponentFactoryProxy
, and the forwardRef
call really serves no purpose.
With the following changes:
- return forwardRef((props, ref) {
- return jsFactoryProxy({
- ...props,
- 'ref': ref,
- }, props['children']);
- // Convert DOM props for the HOC so the consumer API callbacks that involve events receive Dart `SyntheticEvent`s.
- }, displayName: '${displayName ?? jsClassComponent.displayName}');
+ return jsFactoryProxy;
The behavior would be exactly the same.
So, why do we need this function at all, if it's just a wrapper around ReactJsComponentFactoryProxy
? Consumers should just use that instead.
# Conflicts: # lib/react_client.dart # lib/react_client/react_interop.dart
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.
A few more nits! The var
vs final
are probably actually #supernits, but the formatting of the if statements is probably worth cleaning up since it does make it harder to read
final refKeys = ['ref', ...additionalRefPropKeys]; | ||
|
||
for (var refKey in refKeys) { | ||
var ref = args[refKey]; |
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.
#nit ref could be final
var ref = args[refKey]; | |
final ref = args[refKey]; |
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.
+1
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.
+10
While grokking our
forwardRef
API, I found myself wanting some implementation examples which could not be found in the documentation comment.I also noticed that consumers had no way to define a
displayName
for the wrapper HOC created byforwardRef
.These changes address both issues by adding extensive examples in the documentation comment for
forwardRef
that mirror the analogous ReactJS forwardRef documentation, and by adding adisplayName
argument to the function which then gets set on the JS side via a call todefineProperty
.FYA: @greglittlefield-wf @joebingham-wk @sydneyjodon-wk