Search code examples
react-nativeasyncstorage

How to initialize AsyncStorage variable in React Native?


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>
    );
  }
}

Solution

  • 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 .