React-native: Switch does not save state when swipe gesture is used

Created on 24 Aug 2017  路  21Comments  路  Source: facebook/react-native

Is this a bug report?

Yes

Have you read the Contributing Guidelines?

Yes

Then, specify:

  • Target Platform: 22

  • Development Operating System: Windows

  • Build tools: "23.0.1"

(edits by @hramos)
Environment

react-native -v:
image

node -v:
image

npm -v:
image

yarn --version:
image

Steps to Reproduce

(Write your steps here:)

  1. Create wrapper component for Switch

//@flow
import React, { PureComponent } from "react";
import { Switch } from "react-native";
import PropTypes from "prop-types";

export default class Switcher extends PureComponent {
  static propTypes = {
    value: PropTypes.bool.isRequired,
    onToggle: PropTypes.func.isRequired
  };

  render() {
    const { onToggle, value } = this.props;
    return (
      <Switch
        onValueChange={onToggle}
        value={value}
        tintColor="#dadada"
        thumbTintColor={value ? "#2287e1" : "#ffffff"}
        onTintColor="#a7cff3"
      />
    );
  }
}

  1. Create component
class MyData extends PureComponent {
 constructor(props) {
    super(props);
    this.state = { switchValue: false };
  }
 toggleSwitch = value => {
    this.setState({ switchValue: value });
    console.log(`Switch 1 is: ${value}`);
  };
...
render(){
...
 <Switcher
                  value={this.state.switchValue}
                  onToggle={this.toggleSwitch}
                />
...}
}
  1. Run project
  2. Make as shown in gif

Expected Behavior

Save start state into Switch

(Write what you thought would happen.)

Actual Behavior

Crash when pulling

Reproducible Demo

(Paste the link to an example project and exact instructions to reproduce the issue.)

Good first issue Help Wanted Locked

Most helpful comment

Is this still an Issue ? If so, Can I pick this up ?

All 21 comments

Hey, thanks for reporting this issue!

It looks like your description is missing some necessary information, specifically I do not see any mention of the React Native version you are using. Can you please add all the details specified in the template? This is necessary for people to be able to understand and reproduce the issue being reported.

Environment

react-native -v:
image

node -v:
image

npm -v:
image

yarn --version:
image

Thanks, I added them to your original post.

@KirillTarasenko I've made a snack for you here: https://snack.expo.io/r1mGumMt-

It works, and I've just copied and pasted your code. I'm not sure if you can provide any other details for your issue? Maybe double-check your code and make sure it's not something else you've misspelt or something.

@zibs Are you A) on android and B) pulling the switch using a a swipe motion to the left rather than a tap? The bug is on https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitch.java#L32 -- what happens is that for some reason SwitchCompat calls setChecked with true -- but since our internal state is already checked===true, we set mAllowChange to false, no event is fired to the JS, and we never get called again with setOn to reset mAllowChange.

@rhagigi Here is a snack with Android: https://snack.expo.io/HyIohQzKW - It seems to be working fine here as well. I'm able to drag my cursor (not a replacement for the thumb, I realize.) as well as click to make it switch.

Let me know if you see anything else awry here...

@zibs I'm able to recreate on that snack using Expo on my google pixel. You might need to drag around a few times and make sure you really get that quick drag "swipe" action in there.

Easy way to recreate is to drag to the left when the switch is already in the off state.

FWIW I already researched this issue and debugged it (see above) and know it is a problem.

Thanks @rhagigi for investigating. I've marked this as a good first task given that a potential fix has been suggested above.

Unable to replicate on the emulator using RN 0.48.2 - is this still a problem?

Last I checked, like 2 weeks ago, yes. How are you replicating the swipe gesture on an emulator? You really have to swing the mouse to the left while dragging the switch to recreate it on the emulator. Seems to be easier to recreate if the switch is off and then you swipe to the left

@rhagigi seems to be working fine for me ... this is me trying to aggressively swing my mouse to get it to break
out

Not sure about emulator but with the above linked Snack, latest version of Expo, and my up-to-date Pixel on Oreo, the issue still recreates with a quick swipe to the left easily. Try turning the switch off and then swiping to the left, not necessarily dragging the handle. Keep in mind that finger swipes don't necessarily drag on the handle itself.

Hi. I want to clarify a problem. The component expecting to change flag (true -> false or false -> true), but if you save position of point after move from the edge to the edge this reproduce problem.

Start with flag "true":
start switch off position

Start with flag "false":
start switch on position

The surefire way to reproduce this bug is to start dragging, and then return to the state you started with (by letting go at some point before the half way point). The bug occurs when started from both true and false states.

That being said, I'm still seeing it on Android with RN-0.48.0

Is this still an Issue ? If so, Can I pick this up ?

I am using React Native CLI: 2.0.1
React Native: 0.55.4
And still, the component doesn't work for me.

@zibs Even though I copied and pasted it, it still doesn't work on iOS or Android.

Doesn't work for me too, the value is changed yes, but the UI component keeps turnin false, or true in both ways.

react-native-cli: 2.0.1
react-native: 0.55.4

I fixed it by adding a default state and a on changed state in the React Native App.

Hi all. It has not reproduce in RN 0.55.1. That way the issue have solution - update RN.

Seems fine then, ping me to if something goes wrong here.

Was this page helpful?
0 / 5 - 0 ratings