0

I have a problem with React Native Navigation Library, The problem is that I implemented logout in my application that forget the AsyncStorage presistent data, the problem starts when I log to another account without restarting the application, I find that the navigation drawer does not sense the change in AsyncStorage although I update the state depending on returned value from AsyncStorage as if it is cached, so I want a method to refresh the navigation draw or flush the navigation drawer cached view once I made a logout out and re-logged to another account to change the name and thumbnail content.

I tried to find any event listener or any callback where I can replace with my own logic but I didn't find anything closely related. I also tried to replace AsyncStorage with axios call directly to fetch the user but nothing worked.

My Navigator Code:

import {createStackNavigator, createAppContainer, createDrawerNavigator} from 'react-navigation';
import {
    Login,
    Register,
    ShowProperty,
    AllProps,
    Splash,
    Search,
    SearchResult,
    EditProfile,
    AddProperty,
    Home,
    HomeSearch,
    Contact,
    About,
} from "./pages";
import {NavDrawer} from "./components";
import {Dimensions} from 'react-native';


const StackNavigator = createStackNavigator(
    {
        Welcome: {
            screen: Splash
        },
        Register: {
            screen: Register
        },
        Login: {
            screen: Login
        },
        ShowProps: {
            screen: AllProps
        },
        ShowProp: {
            screen: ShowProperty
        },
        Search: {
            screen: Search
        },
        SearchResult: {
            screen: SearchResult
        },
        EditProfile: {
            screen: EditProfile
        },
        AddProperty: {
            screen: AddProperty
        },
        Home: {
            screen: Home,
        },
        HomeSearch: {
            screen: HomeSearch,
        },
        About: {
            screen: About,
        },
        Contact: {
            screen: Contact,
        },
    },
    {
        initialRouteName: "Welcome",
        headerMode: "none",
        duration: 500,
        lazy: true,
    }
);

const DrawerNavigation = createDrawerNavigator({
    Drawer: {
        screen: NavDrawer,
    },
    Application: StackNavigator,
}, {
    initialRouteName: "Application",
    headerMode: "none",
    duration: 500,
    lazy: true,
    contentComponent: NavDrawer,
    drawerWidth: Dimensions.get('window').width,
    drawerPosition: 'right',
});

export default createAppContainer(DrawerNavigation);



 and this is my custom drawer code:

import React, {Component} from 'react';
import {ActivityIndicator, Image, ImageBackground, StyleSheet, View, TouchableOpacity} from 'react-native';
import Responsive from "./Responsive";
import AsyncStorage from '@react-native-community/async-storage';
import {FontText} from "./index";
import Icon from 'react-native-vector-icons/EvilIcons';
import axios from 'axios';
import {NavigationActions, StackActions} from "react-navigation";

class NavDrawer extends Component {
    state = {
        profile_picture: null,
        name: null,
    };

    componentDidMount = async () => {
        const user = await AsyncStorage.getItem('@UserData:user');
        if(user !== null){
            let {first_name, last_name, profile_picture} = JSON.parse(user).data;
            console.log(first_name, last_name, profile_picture);
            let stateObj = {
                profile_picture: profile_picture ? profile_picture : null,
                name: first_name && last_name ? first_name +" "+ last_name : null,
            };
            this.setState({
                ...stateObj
            });
        }
    };

    handleNavigation = (routeName) => (e) => {
        this.props.navigation.closeDrawer();
        this.props.navigation.navigate(routeName);
    };

    resetAndNavigate = (route) => {
        let navigator = StackActions.reset({
            index: 0,
            actions: [
                NavigationActions.navigate({
                    routeName: route,
                }),
            ],
        });
        this.props.navigation.dispatch(navigator);
    };

    clearCredentials = async (e) => {
        try{
            await AsyncStorage.clear();
            this.resetAndNavigate("Login");
        }
        catch (e) {
            this.resetAndNavigate("Login");
        }
    };

    render() {
        return (
                <ImageBackground source={require('../images/drawer-image.jpg')} style={style.backgroundStyle}>
                    <View style={style.infoWrapper}>
                        <Image source={this.state.profile_picture ?
                            {uri: this.state.profile_picture} :
                            require('../images/man.jpg')
                        } style={style.img}
                        />
                        <FontText wFont={'bold'} style={style.nameStyle}>
                            {this.state.name ? this.state.name : "Loading.."}
                        </FontText>
                    </View>
                    <View style={style.navigators}>
                        <TouchableOpacity onPress={this.handleNavigation('Home')}>
                            <FontText style={style.nameStyle}>
                                Home
                            </FontText>
                        </TouchableOpacity>
                        <TouchableOpacity onPress={this.handleNavigation('About')}>
                            <FontText style={style.nameStyle}>
                                About us
                            </FontText>
                        </TouchableOpacity>
                        <TouchableOpacity onPress={this.handleNavigation('Contact')}>
                            <FontText style={style.nameStyle}>
                                Contact us
                            </FontText>
                        </TouchableOpacity>
                        <TouchableOpacity onPress={this.clearCredentials}>
                            <FontText style={style.nameStyle}>
                                Logout
                            </FontText>
                        </TouchableOpacity>
                        <TouchableOpacity style={style.dismiss} onPress={this.props.navigation.closeDrawer}>
                                <Icon name={"close"} color={"#fff"} size={35}/>
                        </TouchableOpacity>
                    </View>
                </ImageBackground>

        );
    }
}

export default NavDrawer;

The expected is when I logged out and re-login with another account is to see the name and photo of current user in drawer.

The actual behavior is that navigation drawer caches the custom component for the drawer and when I log with another user I see the information of the previous user.

  • I would probably create a service and update the user's information in there so that it'll be a singleton across the app. – Sheri Kwong Aug 06 '19 at 20:10
  • Then how can I do that ? The actual behavior in front of me that it loads one time then caches a static view and does not change – Mohamed Mostafa El-Assy Aug 07 '19 at 10:36
  • Creating service - https://angular.io/tutorial/toh-pt4 You'll need to create observables and subscribe to them to get updates. Essentially, you would get your AJAX response and pass it on in the Observable's `next()`. Component's subscribed to that observable will get the update.With BehaviorSubject, all subscriptions will receive updates regardless of component load activation. Don't forget to unsubscribe upon destroying the component. Here's a good tutorial: https://coursetro.com/posts/code/149/RxJS-Subjects-Tutorial---Subjects,-BehaviorSubject,-ReplaySubject-&-AsyncSubject – Sheri Kwong Aug 07 '19 at 18:43

0 Answers0