Search code examples
react-nativeasynchronouslogoutreact-native-navigation

navigation.navigate(screenName) not working in React Native


App.js

import React, { Component } from 'react';
import { View } from 'react-native';
import Route from './app/components/Navigation/Route';
import FlashMessage from "react-native-flash-message";

// create a component
const App = () => {
    return (
      <View style={{flex:1}}>
        <Route/>
        <FlashMessage position="top" />
      </View>
    );
};

//make this component available to the app
export default App;

Route.js

import React, { Component, useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import 'react-native-gesture-handler';
import AsyncStorage from '@react-native-async-storage/async-storage';;

import Authstack from './Authstack';
import AppStack from './Appstack';

function Route() {

  const [token, setToken] = useState('');

  useEffect(()=>{
    loadApp()
  },[]);

  loadApp = async()=>{
    const loggedToken =  await AsyncStorage.getItem('userToken');
    setToken(loggedToken);
  }

    return (
      <NavigationContainer>
        { (token ? <AppStack/> : <Authstack/>)}
      </NavigationContainer>
    );
  }

  export default Route;

Authstack.js

import React from 'react';
import 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/Ionicons';
// import Authstack from './Authstack';

import {createNativeStackNavigator} from '@react-navigation/native-stack';


import {Login, Profile} from '..';
import AppStack from  './Appstack';


export default function Authstack(){
    const Stack = createNativeStackNavigator();
    return(
        <Stack.Navigator initialRouteName='Login'>
            <Stack.Screen name="Login" component={Login} options={{ title: 'Login' ,headerStyle: { backgroundColor: '#b61b1b', },
                headerTintColor: 'white',headerTitleStyle: {fontWeight: 'bold',},}} />
            <Stack.Screen name="AppStack" component={AppStack} options={{ header: false }}/>
        </Stack.Navigator>
        
    );
}

Appstack.js

import React from 'react';
import Icon from 'react-native-vector-icons/Ionicons';
import { createDrawerNavigator } from '@react-navigation/drawer';

import SidebarMenu from  './SidebarMenu';


import {Profile, Salary, Attendance, Insurance, Leave, Loan,Logout,Sidebar} from '..';

export default function AppStack(){
const Drawer = createDrawerNavigator();

  const loadIcon =(name)=>{
    return <Icon name={name} size={20} color='#b61b1b'/>
  }

    return(
          <Drawer.Navigator screenOptions={{headerStyle: {
            backgroundColor: '#b61b1b', },headerTintColor: '#fff',headerTitleStyle: {fontWeight: 'bold' },}}
            drawerContentOptions={{activeTintColor: '#e91e63',itemStyle: { marginVertical: 5 }, }} 
            drawerContent={(props)=> <SidebarMenu {...props} /> }>
            <Drawer.Screen name="Profile" component={Profile} options={{drawerIcon: () => (loadIcon('person-circle-outline')),}} />
            <Drawer.Screen name="Attendance" component={Attendance} options={{drawerIcon: () => (loadIcon('alarm-outline')),}} />
            <Drawer.Screen name="Salary" component={Salary} options={{drawerIcon: () => (loadIcon('cash-outline')),}} />
            <Drawer.Screen name="Leave" component={Leave} options={{drawerIcon: () => (loadIcon('calendar-outline')),}} />
            <Drawer.Screen name="Loan" component={Loan} options={{drawerIcon: () => (loadIcon('business-outline')),}} />
            <Drawer.Screen name="Logout" component={Logout} options={{drawerIcon: () => (loadIcon('exit-outline')),}} />
          </Drawer.Navigator>
        
    );
}

Logout.js

import { View, Text,Button } from 'react-native'
import React from 'react'


const Logout = ({navigation}) => {
  return (
    <View>
      <Text>Logout</Text>
      <Button title="Logout" onPress={()=>navigation.navigate('Authstack',{screen:'Login'})} />
    </View>
  )
}

export default Logout

When I click Logout button page not take any action. I am trying to navigate to login page in Authstack in stack navigator from drawer navigator Logout screen but not working. How to fix this.

I am trying to navigate to login page in Authstack in stack navigator from drawer navigator Logout screen but not working.


Solution

  • You are rendering AppStack and AuthStack conditionally based on whether the user is logged in or not:

    { (token ? <AppStack/> : <Authstack/>)}
    

    In AuthStack you have included the AppStack again, but not the other way around (so when you are logged in, the AuthStack doesn't exist!). How ever this is bad practice and I recommend you to add the both stacks (AppStack and AuthStack) in a root stack (e.g. stackNavigator). You can then set the initial route based on the status of the user (when the token is undefined, open the AuthStack, otherwise open the AppStack). Then you don't have to embed the AppStack in the AuthStack and you should be able to open the AuthStack when logging out. An example would be:

    import React, { Component, useEffect, useState } from 'react';
    import { NavigationContainer } from '@react-navigation/native';
    import 'react-native-gesture-handler';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    import {createNativeStackNavigator} from '@react-navigation/native-stack';
    
    import Authstack from './Authstack';
    import AppStack from './Appstack';
    const Stack = createNativeStackNavigator();
    
    function Route() {
      const handleNavigationRef = (node) => {
            if (node === null) {
                return;
            }
            AsyncStorage.getItem('userToken').then(value => {
                if (value) {
                    return;
                }
                node.navigate("auth");
            });
        };
    
    
        return (
          <NavigationContainer ref={handleNavigationRef}>
              <Stack.Navigator>
                  <Stack.Screen name="app" component={AppStack} />
                  <Stack.Screen name="auth" component={AuthStack} />
              </Stack.Navigator>
          </NavigationContainer>
        );
      }
    
      export default Route;