Search code examples
asynchronousreact-nativenative-baseasyncstorage

React Native - Async storage information is extracted after componentWillMount()


I am storing if a checkbox is checked or not using AsyncStorage. When I reload the app, I see from logs that inside the asynchronous variable the correct information is stored. But, it is loaded after componentWillMount. Because of that, the checkbox does not appear checked, as it should be.

I think a good workaround will be to change the checkbox properties inside the asynchronous function. Do you think that would be a good solution? Do you have other suggestions for showing the correct checkbox value?

My code:

constructor(props) {
    super(props)
    this.state = {isChecked: false}
    this.switchStatus = this.switchStatus.bind(this)
  }

  async getCache(key) {
    try {
      const status = await AsyncStorage.getItem(key);
      if (status == null)
        status = false
      console.log("my async status is " + status)
      return status
    } catch(error) {
      console.log("error", e)
    }
  }

  componentWillMount(){
    // key string depends on the object selected to be checked
    const key = "status_" + this.props.data.id.toString()
    this.getCache = this.getCache.bind(this)
    this.setState({isChecked: (this.getCache(key) == 'true')})
    console.log("my state is" + this.state.isChecked)
  }

  switchStatus () {
    const newStatus = this.state.isChecked == false ? true : false
    AsyncStorage.setItem("status_" + this.props.data.id.toString(), newStatus.toString());
    console.log("hi my status is " + newStatus)
    this.setState({isChecked: newStatus})
  }

  render({ data, onPress} = this.props) {
    const {id, title, checked} = data
    return (
      <ListItem button onPress={onPress}>
        <CheckBox
          style={{padding: 1}}
          onPress={(this.switchStatus}
          checked={this.state.isChecked}
        />
        <Body>
          <Text>{title}</Text>
        </Body>
        <Right>
          <Icon name="arrow-forward" />
        </Right>
      </ListItem>
    )
  }

There is no difference if I put everything in componentWillMount in the constructor.


Solution

  • Thank you for your answers. I am pretty sure await will work too, but I solved the problem before getting an answer. What I did was set the state to false in the beginning, and then update it in getCache. This way, it will always be set after getting the information from the local phone storage.

    async getCache(key) {
        try {
          let status = await AsyncStorage.getItem(key);
          if (status == null) {
            status = false
          }
          this.setState({ isChecked: (status == 'true') })
        } catch(e) {
          console.log("error", e);
        }
      }