Tokyo
Tokyo

Reputation: 211

Navigation issue in Reat Naivgation, React Native

I am using react-navigation 5 in my mobile app and I am stuck in implementing a log-off feature.

The scenario is I have a stack navigator and a bottom tab navigator in my app. The app starts with the stack navigator (Login feature and Reset Password Feature) and on login goes to the dashboard Page which is from the bottom tab navigator. Now on the Dashboard page, I am implementing a logout feature which when clicked should take me to the login page (part of stack navigator), and no matter what I try it keeps giving me errors like these

The action 'RESET' with payload {"index":0,"routes":[{"name":"AuthNavigator"}]} was not handled by any navigator.

Here are my code snippets right from start

Component Called from App.js

import React, { useState, useEffect, useContext } from "react";
import { ActivityIndicator } from "react-native";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Center } from "../../components/Center";
import { AuthContext } from "../authentication/AuthProvider";
import { NavigationContainer } from "@react-navigation/native";
import { AuthNavigator } from "./AuthNavigator"; 
import { MainTabNavigator } from "./MainTabNavigator"; 


export default function App() {
  const { user, login } = useContext(AuthContext);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // check if the user is logged in or not
    //AsyncStorage.removeItem("user") //- uncomment this and refresh emulator to start from login screen
    AsyncStorage.getItem("user")
      .then(userString => {
        if (userString) {
          login();
        }
        setLoading(false);
      })
      .catch(err => {
        console.log(err);
      });
  }, []);

  if (loading) {
    return (
      <Center>
                <ActivityIndicator size="large" />
      </Center>

    );
  }
  return (
    <NavigationContainer>
      {user ? <MainTabNavigator /> : <AuthNavigator />}
    </NavigationContainer>
  );

}

AuthNavigator.js

import React from "react";
import { createStackNavigator } from '@react-navigation/stack';
import Login from '../authentication/Login';
import ResetPassword from '../authentication/ResetPassword';
import { MainTabNavigator } from "./MainTabNavigator"; 


const Stack = createStackNavigator();

export const AuthNavigator = () => {
    return (
        <Stack.Navigator initialRouteName="Login">
          <Stack.Screen name="Login" component={Login} />
          <Stack.Screen name="ResetPassword" options={{headerTitle: "Reset Password"}} component={ResetPassword} />
        </Stack.Navigator>
      );
}

MainTabNavigator.js

import * as React from 'react';
import { Text, View, Image, StyleSheet, Platform } from 'react-native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import DashboardView from '../dashboard/DashboardView';
import Search from '../searchLoan/Search';
import { colors } from '../../styles';

const iconHome = require('../../../assets/images/tabbar/home.png');
const iconGrids = require('../../../assets/images/tabbar/grids.png');
const searchIcon = require('../../../assets/images/pages/search_24px.png');

const Tab = createBottomTabNavigator();

const tabData = [
  {
    name: 'Dashboard',
    component: DashboardView,
    icon: iconHome,
  },
  {
    name: 'Search',
    component: Search,
    icon: searchIcon,
  },
];

export const MainTabNavigator = () => {
  return (
    <Tab.Navigator tabBarOptions={{ style: { height: Platform.OS === 'ios' ? 90 : 50 } }}>
      {tabData.map((item, idx) => (
        <Tab.Screen
          key={`tab_item${idx + 1}`}
          name={item.name}
          component={item.component}
          options={{
            tabBarIcon: ({ focused }) => (
              <View style={styles.tabBarItemContainer}>
                <Image
                  resizeMode="contain"
                  source={item.icon}
                  style={[styles.tabBarIcon, focused && styles.tabBarIconFocused]}
                />
              </View>
            ),
            tabBarLabel: ({ focused }) => <Text style={{ fontSize: 12, color: focused ? colors.primary : colors.gray }}>{item.name}</Text>,
            title: item.name,
          }}
        />
      ))}
    </Tab.Navigator>
  );
};

const styles = StyleSheet.create({
  tabBarItemContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    borderBottomWidth: 2,
    borderBottomColor: colors.white,
    paddingHorizontal: 10,
    bottom: Platform.OS === 'ios' ? -5 : 0,
  },
  tabBarIcon: {
    width: 23,
    height: 23,
  },
  tabBarIconFocused: {
    tintColor: colors.primary,
  },
});

DashboardView.js

import React , {useContext }from 'react';
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
import {Header} from 'react-native-elements';
import AntIcon from "react-native-vector-icons/AntDesign";
import { colors, fonts } from '../../styles';
import AmountDetails from './AmountDetails';
import DashboardFields from './DashboardFields';
import { AuthContext } from "../authentication/AuthProvider";
import { CommonActions } from "@react-navigation/native";


export default function DashboardView(props) {
    const appLogOut = () => {
        const { logout } = useContext(AuthContext);
        console.log('props', props)
        if(logout){
           // console.log("Navigation Object", navigation)
           props.navigation.dispatch(
            CommonActions.reset({
               index: 0,
               routes: [{ name: "AuthNavigator" }],
           }));

        }
    }
    return (
        <View style={styles.container}>
            <Header containerStyle = {{backgroundColor: colors.primary}}
            centerComponent={{ text: 'Dashboard', style: { color: colors.white, backgroundColor: colors.primary } }}
            rightComponent = <TouchableOpacity onPress={appLogOut()}><AntIcon name="logout" color="white" size={25}/></TouchableOpacity>
            />           
            <View style={styles.container}>
                <View>
                    <AmountDetails />
                </View>
                <View style={styles.dashboardFields}>
                    <DashboardFields />
                </View>
            </View>
        </View>
       
    );
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: colors.gray,
    },
    dashboardFields: {
        marginTop: 20,
    },
});

Upvotes: 2

Views: 1430

Answers (2)

satya164
satya164

Reputation: 10152

As the other answer said, you have incorrect route name (AuthNavigator).

However, you're conditionally defining screens based on if the user is logged in. You don't need to do anything extra when logging out. Conditionally defining screens means React Navigation can automatically handle which screen to show when the conditional changes.

So you need to remove the code which does reset.

From the docs:

It's important to note that when using such a setup, you don't need to manually navigate to the Home screen by calling navigation.navigate('Home') or any other method. React Navigation will automatically navigate to the correct screen when isSigned in changes - Home screen when isSignedIn becomes true, and to SignIn screen when isSignedIn becomes false. You'll get an error if you attempt to navigate manually.

More details: https://reactnavigation.org/docs/auth-flow/

Upvotes: 0

Asusoft
Asusoft

Reputation: 362

You should try calling the login screen directly, not the whole stack.

CommonActions.reset({
               index: 0,
               routes: [{ name: "Login" }],
           }));

Upvotes: 0

Related Questions