Skip to content
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

[NativeMethodsMixin] CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class #21585

Closed
wants to merge 7 commits into from

Conversation

empyrical
Copy link
Contributor

This PR converts the use of NativeMethodsMixin in CheckBox.android.js, and converts it to an ES6-style class.

Test Plan:

I have tested it in RNTester, and I ran in to no issues.

Release Notes:

[GENERAL] [ENHANCEMENT] [Libraries/Components/CheckBox/CheckBox.android.js] - Convert NativeMethodsMixin to forwardedRef, converted to ES6 class

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 9, 2018
@empyrical empyrical requested a review from elicwhite October 9, 2018 04:12
Copy link

@analysis-bot analysis-bot left a comment

Choose a reason for hiding this comment

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

Code analysis results:

  • eslint found some issues.

const React = require('React');
const ReactNative = require('ReactNative');

Choose a reason for hiding this comment

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

no-unused-vars: 'ReactNative' is assigned a value but never used.

@empyrical empyrical force-pushed the checkbox-mixin-remove branch 2 times, most recently from 6001e2b to 44a48dd Compare October 9, 2018 04:14
Copy link

@analysis-bot analysis-bot left a comment

Choose a reason for hiding this comment

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

Code analysis results:

  • eslint found some issues.

const React = require('React');
const ReactNative = require('ReactNative');

Choose a reason for hiding this comment

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

no-unused-vars: 'ReactNative' is assigned a value but never used.

Copy link

@analysis-bot analysis-bot left a comment

Choose a reason for hiding this comment

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

Code analysis results:

  • eslint found some issues.

const React = require('React');
const ReactNative = require('ReactNative');

Choose a reason for hiding this comment

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

no-unused-vars: 'ReactNative' is assigned a value but never used.

|}>;

type NativeProps = $ReadOnly<{|
...Props,
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is true. The native component doesn't take disabled or value for example.

/**
* Used to get the ref for the native checkbox
*/
ref?: ?Object,
Copy link
Member

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 have a type for this yet in Flow but I'd rather it be $FlowIssue here than Object.

@RSNara RSNara changed the title CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class [NativeMethodsMixin] CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class Oct 9, 2018
@empyrical empyrical changed the title [NativeMethodsMixin] CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class [WIP][NativeMethodsMixin] CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class Oct 11, 2018
Copy link
Contributor

@RSNara RSNara left a comment

Choose a reason for hiding this comment

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

Looks mostly good, but I'm not sure if the ref forwarding is set up correctly.

* Used to get the ref for the native checkbox
*/
// $FlowFixMe: Properly type the ref prop type
ref?: $FlowIssue,
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm... ref like key isn't a prop, so my first instinct would be to omit it from the flow CommonProps type. Do we really need this here?

};

_setAndForwardRef = nativeRef => {
const {ref} = this.props;
Copy link
Contributor

@RSNara RSNara Oct 10, 2018

Choose a reason for hiding this comment

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

As far as I'm aware, this won't work because ref isn't a prop (i.e: this.props.ref will be undefined). What we really need is something like this:

class CheckBox extends React.Component<Props> {
   _setAndForwardRef = nativeRef => {
     const {forwardedRef} = this.props;
     // ...
   }
}

CheckBox2 = React.forwardRef((props, ref) => <CheckBox {...props} forwardedRef={ref}/>);

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, it has to be passed in as a prop of a different name than ref (like forwardedRef)

Libraries/Components/CheckBox/CheckBox.android.js Outdated Show resolved Hide resolved
@elicwhite
Copy link
Member

@empyrical, you did a bunch of work to validate that this ref set and forwarding work. Do you think you could add some unit tests for this component that check that behavior? It would be super valuable to set a good example for other components we will want to be updating as well.

@empyrical
Copy link
Contributor Author

Do you think a new section to the RNTester page that uses its ref would cover it? (like a <Button /> that toggles the state of the checkbox, perhaps)

I have a PR coming up that includes a better way to handle these forwarded refs in classes, and would like to rebase this and address the code review points once it makes its way in. (Will also rename the ref prop to forwardedRef)

The nullthrows thing I did because the type of the ref is nullable, and Flow understandably does not like trying to access a method on it without a null check. This is also how RefreshControl does it:

nullthrows(this._nativeRef).setNativeProps({
refreshing: this.props.refreshing,
});

And I didn't do this._nativeRef && this._nativeRef.method() because if the ref handling broke at some point, then it would be a silent failure.

@elicwhite
Copy link
Member

I think you can test these things using a Jest test which would be run fast and in an automated way. I think this would be better here than an RNTester example.

@empyrical empyrical force-pushed the checkbox-mixin-remove branch from 40cd9b1 to 70d3553 Compare October 18, 2018 06:21
@empyrical
Copy link
Contributor Author

Rebased this and changed it to properly forward refs using setAndForwardRef.

},
class CheckBox extends React.Component<Props> {
_nativeRef: ?React.ElementRef<CheckBoxNativeType> = null;
_setNativeRef = setAndForwardRef({
Copy link
Member

Choose a reason for hiding this comment

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

We should flow type setAndForwardRef to ensure that getForwardedRef and setLocalRef operate on the same ref type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should that be done in this PR, or a separate PR? (in case this one needs to be reverted)

Copy link
Member

Choose a reason for hiding this comment

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

Separate is best. I just noticed as part of some weirdness in how it is being used here.

@empyrical empyrical changed the title [WIP][NativeMethodsMixin] CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class [NativeMethodsMixin] CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class Oct 18, 2018
@empyrical empyrical force-pushed the checkbox-mixin-remove branch from 96a4b94 to 61d3aca Compare October 26, 2018 03:44
Copy link
Contributor

@RSNara RSNara left a comment

Choose a reason for hiding this comment

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

Looks good! 😁

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

RSNara has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@react-native-bot
Copy link
Collaborator

@empyrical merged commit 28de61e into facebook:master.

@facebook facebook locked as resolved and limited conversation to collaborators Nov 2, 2018
@react-native-bot react-native-bot added the Merged This PR has been merged. label Nov 2, 2018
t-nanava pushed a commit to microsoft/react-native-macos that referenced this pull request Jun 17, 2019
facebook#21585)

Summary:
This PR converts the use of `NativeMethodsMixin` in `CheckBox.android.js`, and converts it to an ES6-style class.
Pull Request resolved: facebook#21585

Reviewed By: TheSavior

Differential Revision: D12827768

Pulled By: RSNara

fbshipit-source-id: c113c221335e61e015a20bbb6bcff5f9837f9022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants