CheckBox: Convert NativeMethodsMixin to forwardedRef, convert to class (#21585)
Summary: This PR converts the use of `NativeMethodsMixin` in `CheckBox.android.js`, and converts it to an ES6-style class. Pull Request resolved: https://github.com/facebook/react-native/pull/21585 Reviewed By: TheSavior Differential Revision: D12827768 Pulled By: RSNara fbshipit-source-id: c113c221335e61e015a20bbb6bcff5f9837f9022
This commit is contained in:
parent
14e1628ba8
commit
28de61e9f0
|
@ -9,21 +9,76 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes');
|
||||
const NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('React');
|
||||
const StyleSheet = require('StyleSheet');
|
||||
|
||||
const createReactClass = require('create-react-class');
|
||||
const requireNativeComponent = require('requireNativeComponent');
|
||||
const nullthrows = require('nullthrows');
|
||||
const setAndForwardRef = require('setAndForwardRef');
|
||||
|
||||
const RCTCheckBox = requireNativeComponent('AndroidCheckBox');
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
import type {SyntheticEvent} from 'CoreEventTypes';
|
||||
import type {NativeComponent} from 'ReactNative';
|
||||
|
||||
type DefaultProps = {
|
||||
value: boolean,
|
||||
disabled: boolean,
|
||||
};
|
||||
type CheckBoxEvent = SyntheticEvent<
|
||||
$ReadOnly<{|
|
||||
target: number,
|
||||
value: boolean,
|
||||
|}>,
|
||||
>;
|
||||
|
||||
type CommonProps = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
|
||||
/**
|
||||
* Used in case the props change removes the component.
|
||||
*/
|
||||
onChange?: ?(event: CheckBoxEvent) => mixed,
|
||||
|
||||
/**
|
||||
* Invoked with the new value when the value changes.
|
||||
*/
|
||||
onValueChange?: ?(value: boolean) => mixed,
|
||||
|
||||
/**
|
||||
* Used to locate this view in end-to-end tests.
|
||||
*/
|
||||
testID?: ?string,
|
||||
|}>;
|
||||
|
||||
type NativeProps = $ReadOnly<{|
|
||||
...CommonProps,
|
||||
|
||||
on?: ?boolean,
|
||||
enabled?: boolean,
|
||||
|}>;
|
||||
|
||||
type CheckBoxNativeType = Class<NativeComponent<NativeProps>>;
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
...CommonProps,
|
||||
|
||||
/**
|
||||
* The value of the checkbox. If true the checkbox will be turned on.
|
||||
* Default value is false.
|
||||
*/
|
||||
value?: ?boolean,
|
||||
|
||||
/**
|
||||
* If true the user won't be able to toggle the checkbox.
|
||||
* Default value is false.
|
||||
*/
|
||||
disabled?: ?boolean,
|
||||
|
||||
/**
|
||||
* Used to get the ref for the native checkbox
|
||||
*/
|
||||
forwardedRef?: ?React.Ref<CheckBoxNativeType>,
|
||||
|}>;
|
||||
|
||||
const RCTCheckBox = ((requireNativeComponent(
|
||||
'AndroidCheckBox',
|
||||
): any): CheckBoxNativeType);
|
||||
|
||||
/**
|
||||
* Renders a boolean input (Android only).
|
||||
|
@ -80,85 +135,64 @@ type DefaultProps = {
|
|||
* @keyword checkbox
|
||||
* @keyword toggle
|
||||
*/
|
||||
let CheckBox = createReactClass({
|
||||
displayName: 'CheckBox',
|
||||
propTypes: {
|
||||
...DeprecatedViewPropTypes,
|
||||
/**
|
||||
* The value of the checkbox. If true the checkbox will be turned on.
|
||||
* Default value is false.
|
||||
*/
|
||||
value: PropTypes.bool,
|
||||
/**
|
||||
* If true the user won't be able to toggle the checkbox.
|
||||
* Default value is false.
|
||||
*/
|
||||
disabled: PropTypes.bool,
|
||||
/**
|
||||
* Used in case the props change removes the component.
|
||||
*/
|
||||
onChange: PropTypes.func,
|
||||
/**
|
||||
* Invoked with the new value when the value changes.
|
||||
*/
|
||||
onValueChange: PropTypes.func,
|
||||
/**
|
||||
* Used to locate this view in end-to-end tests.
|
||||
*/
|
||||
testID: PropTypes.string,
|
||||
},
|
||||
class CheckBox extends React.Component<Props> {
|
||||
_nativeRef: ?React.ElementRef<CheckBoxNativeType> = null;
|
||||
_setNativeRef = setAndForwardRef({
|
||||
getForwardedRef: () => this.props.forwardedRef,
|
||||
setLocalRef: ref => {
|
||||
this._nativeRef = ref;
|
||||
},
|
||||
});
|
||||
|
||||
getDefaultProps: function(): DefaultProps {
|
||||
return {
|
||||
value: false,
|
||||
disabled: false,
|
||||
};
|
||||
},
|
||||
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
_rctCheckBox: {},
|
||||
_onChange: function(event: Object) {
|
||||
this._rctCheckBox.setNativeProps({value: this.props.value});
|
||||
_onChange = (event: CheckBoxEvent) => {
|
||||
const value = this.props.value ?? false;
|
||||
nullthrows(this._nativeRef).setNativeProps({value: value});
|
||||
// Change the props after the native props are set in case the props
|
||||
// change removes the component
|
||||
this.props.onChange && this.props.onChange(event);
|
||||
this.props.onValueChange &&
|
||||
this.props.onValueChange(event.nativeEvent.value);
|
||||
},
|
||||
};
|
||||
|
||||
render: function() {
|
||||
let props = {...this.props};
|
||||
props.onStartShouldSetResponder = () => true;
|
||||
props.onResponderTerminationRequest = () => false;
|
||||
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
|
||||
* when making Flow check .android.js files. */
|
||||
props.enabled = !this.props.disabled;
|
||||
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
|
||||
* when making Flow check .android.js files. */
|
||||
props.on = this.props.value;
|
||||
props.style = [styles.rctCheckBox, this.props.style];
|
||||
render() {
|
||||
const {disabled: _, value: __, style, forwardedRef, ...props} = this.props;
|
||||
const disabled = this.props.disabled ?? false;
|
||||
const value = this.props.value ?? false;
|
||||
|
||||
const nativeProps = {
|
||||
...props,
|
||||
onStartShouldSetResponder: () => true,
|
||||
onResponderTerminationRequest: () => false,
|
||||
enabled: !disabled,
|
||||
on: value,
|
||||
style: [styles.rctCheckBox, style],
|
||||
};
|
||||
|
||||
return (
|
||||
<RCTCheckBox
|
||||
{...props}
|
||||
ref={ref => {
|
||||
/* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error when upgrading Flow's support for
|
||||
* React. To see the error delete this comment and run Flow. */
|
||||
this._rctCheckBox = ref;
|
||||
}}
|
||||
{...nativeProps}
|
||||
ref={this._setNativeRef}
|
||||
onChange={this._onChange}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let styles = StyleSheet.create({
|
||||
const styles = StyleSheet.create({
|
||||
rctCheckBox: {
|
||||
height: 32,
|
||||
width: 32,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = CheckBox;
|
||||
/**
|
||||
* Can't use CheckBoxNativeType because it has different props
|
||||
*/
|
||||
type CheckBoxType = Class<NativeComponent<Props>>;
|
||||
|
||||
// $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet.
|
||||
const CheckBoxWithRef = React.forwardRef(function CheckBoxWithRef(props, ref) {
|
||||
return <CheckBox {...props} forwardedRef={ref} />;
|
||||
});
|
||||
|
||||
module.exports = (CheckBoxWithRef: CheckBoxType);
|
||||
|
|
Loading…
Reference in New Issue