Reputation: 55
My app is simple: one button with one state toggleButton
. In constructor toggleButton
is set to the default value false
. When I press the button, the app will start record some sensors and console.log
their data to the chrome debugger screen.
constructor(props) {
super(props);
this.state = {
toggleButton: false
};
}
recordSensors() {
let toggleButton = !this.state.toggleButton;
this.setState({ toggleButton });
if (this.state.toggleButton) {
// start & record some sensors data
} else {
// stop recording
}
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.toggleButton}
onPress={() => this.recordSensors()}
>
<Text style={styles.buttonText}>
{this.state.toggleButton ? 'Stop' : 'Start'}
</Text>
</TouchableOpacity>
<Text>
{this.state.toggleButton ? 'Recording...' : null}
</Text>
</View>
);
}
The weird thing is, the first time I press the button, its text changed to Stop
and the Recording...
text appeared but the app didn't record sensors data. When I press the button again (the second time), then it now records.
But if I change if (this.state.toggleButton)
to if (toggleButton)
then it works fine. I can't understand the logic of it anymore. Can you guys help?
Upvotes: 0
Views: 432
Reputation: 33
A probable explanation for this behavior is that initially react always assumes the state of the toggleButton is true so when you initialize it with false, it first changes the state to true without executing the code, also when you initialize the state with true it does not execute the
let toggleButton= !this.state.toggleButton
so you'd still end up with the same functionality as if the state was first initialized with false.
That's also why when you log the value of the state when initialized with true or false they both give the same value which corresponds to the current state of your toggle button after it is first ran so it's best you first initialize with true
Upvotes: 0
Reputation: 6905
Your problem:
onPress={() => this.recordSensors()}
Fix:
onPress={() => this.recordSensors}
Here is your logic:
In your constructor:
toggleButton = false;
In render:
onPress={() => this.recordSensors()}
Which calls:
//currently this.state.toggleButton == false;
let toggleButton = !this.state.toggleButton; // let toggleButton=true;
this.setState({ toggleButton }); // now state.toggleButton = true;
So now when you click your button, you care call recordSensors() for a second time:
//currently this.state.toggleButton == true;
let toggleButton = !this.state.toggleButton; // let toggleButton =false;
this.setState({ toggleButton }); // now state.toggleButton == false;
Upvotes: 0
Reputation: 30739
You are using
let toggleButton = !this.state.toggleButton;
Where toggleButton
has inverse value of this.state.toggleButton
And, say if, this.state.toggleButton
is false
then toggleButton
will have true
as its value. So, the condition you are specifying is totally different here
if (this.state.toggleButton) //if(false)
And when you do
if(toggleButton) //if(true)
So, notice that condition when you have this.state.toggleButton
as false
or vice-versa
Upvotes: 2