I have tried following this tutorial. It won't display any score at first. What I want to do is there's an initial score of 30. If the user pushes the button, it deducts 20 in it. So when the user reloads the app, it should display a score of 10.
class SupporterMapScreen extends Component<{}> {
...
constructor(props) {
super(props);
this.state = {
isUsed: false,
show: false,
points: 30,
beaconMarkers: {
coordinate: {latitude: 14.554180, longitude: 121.044099},
cost: 20,
},
};
}
componentDidMount = () => AsyncStorage.getItem('points').then((value) => this.setState({ 'points': value }))
createBeacon() {
const { points, beaconMarkers } = this.state;
if(points >= beaconMarkers.cost) {
var totalPoints = points - beaconMarkers.cost;
alert("The beacon has been added!");
this.setState({ isUsed: true, show: true, points: totalPoints });
AsyncStorage.setItem('points', totalPoints);
this.setState({ 'points': totalPoints });
}
else {
...
}
render() {
return (
<View style={styles.container}>
...
<View style = {styles.pointsBar}>
<Text style = {styles.points}>POINTS: {this.state.points}</Text>
</View>
<View style = {styles.beaconPosition}>
<Button
disabled = {this.state.isUsed}
style = {styles.beaconButton}
onPress={ () => Alert.alert(
'Buy Beacon?',
'It costs ' + this.state.beaconMarkers.cost + ' points in order to buy beacon.',
[
{text: 'No'},
{text: 'Yes', onPress: () => this.createBeacon()},
],
{ cancelable: false }
)}
title = 'B'
/>
</View>
</View>
);
}
}
In your componentDidMount
, you should check for falsy values before setting state:
componentDidMount = () =>
AsyncStorage.getItem('points').then((value) => {
if (value) {
this.setState({ 'points': value })
}
})
I recommend using flow-type
or equivalent type checker for your code to find bugs like this more easily .