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

Fix excessive toggles on the Switch component #26496

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 21 additions & 9 deletions Libraries/Components/Switch/Switch.js
Expand Up @@ -92,6 +92,7 @@ class Switch extends React.Component<Props> {
_nativeSwitchRef: ?React.ElementRef<
typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent,
>;
_lastNativeValue: ?boolean;

render(): React.Node {
const {
Expand Down Expand Up @@ -196,26 +197,37 @@ class Switch extends React.Component<Props> {
);
}

_handleChange = (event: SwitchChangeEvent) => {
if (this._nativeSwitchRef == null) {
return;
componentDidUpdate() {
// This is necessary in case native updates the switch and JS decides
// that the update should be ignored and we should stick with the value
// that we have in JS.
const nativeProps = {};
const value = this.props.value === true;

if (this._lastNativeValue !== value && typeof value === 'boolean') {
nativeProps.value = value;
}

// Force value of native switch in order to control it.
const value = this.props.value === true;
if (Platform.OS === 'android') {
this._nativeSwitchRef.setNativeProps({on: value});
} else {
this._nativeSwitchRef.setNativeProps({value});
if (
Object.keys(nativeProps).length > 0 &&
this._nativeSwitchRef &&
this._nativeSwitchRef.setNativeProps
) {
this._nativeSwitchRef.setNativeProps(nativeProps);
}
}

_handleChange = (event: SwitchChangeEvent) => {
if (this.props.onChange != null) {
this.props.onChange(event);
}

if (this.props.onValueChange != null) {
this.props.onValueChange(event.nativeEvent.value);
}

this._lastNativeValue = event.nativeEvent.value;
this.forceUpdate();
};

_handleSwitchNativeComponentRef = (
Expand Down