Skip to content

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

Merged

Conversation

aaronlademann-wf
Copy link
Collaborator

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 by forwardRef.

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 a displayName argument to the function which then gets set on the JS side via a call to defineProperty.


FYA: @greglittlefield-wf @joebingham-wk @sydneyjodon-wk

@aaronlademann-wf aaronlademann-wf force-pushed the 5.4.0/improve-forwardref-examples-and-typing branch from 5c19d8d to 722ee9e Compare January 24, 2020 20:49
+ And update forwardRef documentation to recommend its use
@aaronlademann-wf aaronlademann-wf added this to the 5.4.0 milestone Jan 29, 2020
Copy link
Collaborator

@joebingham-wk joebingham-wk left a 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!

aaronlademann-wf and others added 7 commits January 29, 2020 17:17
+ 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)
/// print(textFieldInputNodeRef.current.value);
/// }
/// ```
ReactJsComponentFactoryProxy forwardRefToJs(
Copy link
Collaborator

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

Copy link
Collaborator Author

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.

Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

Copy link
Collaborator

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.

Copy link
Collaborator

@joebingham-wk joebingham-wk left a 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];
Copy link
Collaborator

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

Suggested change
var ref = args[refKey];
final ref = args[refKey];

Copy link
Collaborator

@joebingham-wk joebingham-wk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Collaborator

@greglittlefield-wf greglittlefield-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+10

@greglittlefield-wf greglittlefield-wf merged commit 546472f into 5.4.0-wip Feb 10, 2020
@greglittlefield-wf greglittlefield-wf deleted the 5.4.0/improve-forwardref-examples-and-typing branch February 16, 2022 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants