Search code examples
reactjsreact-nativereact-native-router-fluxasyncstorage

AsyncStorage getItem not working within drawer with react native router flux


I'm trying to get values within AsyncStorage in my drawer component.I've done conditional rendering for showing login and logout button within drawer.So after successful login ,if there is values within AsynStorage the button within drawer should be Logout instead of Login.But initially after login when drawer is opened the value of AsyncStorageis not getting.It is getting only if I click on a specific item in drawer.So how do I get values within drawer when it is opened?I've done the following

login.js

async saveItem(item, selectedValue) {
    try {
      await AsyncStorage.setItem(item, selectedValue);
    } catch (error) {
      console.error('AsyncStorage error: ' + error.message);
    }
  }

...
....
...
.then((response) => response.json())
      .then((responseData) => {
        this.setState({
          login: responseData
        })
        if (responseData.status == true) {

          this.saveItem('userdetail', responseData.token.access_token);
          this.saveItem('userimage', responseData.user.avatar);
          this.saveItem('user', responseData.user.name);
          Actions.dashBoard();
          this.setState({ isLoading: false });

        } else {
....
}

drawer.js

componentDidMount() {
        AsyncStorage.getItem("user").then(value => {
            this.setState({ name: value })
        })
        console.log(this.state.name);
    }

onPressList = (data, index) => {
        AsyncStorage.getItem("user").then(value => {
            this.setState({ name: value })
        })
        if (this.state.name) {
            if (data.route == "profile")
                Actions.profile();
       ...
      ....
      ...
}
}

render(){
return(
{this.state.name? (
 <ListItem
                            button
                            noBorder
                            onPress={() => this.onPressLogout()}
                        >

                            <Text style={[styles.text, { textAlign: 'left' }]}>
                                Logout
                            </Text>

                        </ListItem>
) : (
 <ListItem
                            button
                            noBorder
                            onPress={() => this.onPressLogin()}
                        >
                            <Text style={[styles.text, { textAlign: 'left' }]}>
                                Login
                            </Text>

                        </ListItem>) }
)
}     

Here within drawer for every listitem I've checking whether name is set or not.It will navigate only if name is there.But the problem is initially within componentDidMount I don't get values in AsyncStorage.Please help me to find a solution.The problem exist only in side bar.I'm getting values in AsyncStorage in all the other screens.Please help.Any help would be really appreciable.Thank you.


Solution

  • The problem is that you are checking for the user before the user has been added to async storage. The reason that it works when you click on an item is because you are checking for the user each time a list-item is clicked. Instead of componentDidMount you could use componentWillUpdate. I'm guessing that when you click on the drawer it will update the component and then check for the user (Since React re-renders the entire Component subtree).

    Hope that helps

        componentWillUpdate() {
            AsyncStorage.getItem("user").then(value => {
                this.setState({ name: value })
            })
            console.log(this.state.name);
        }