React Navigation 5 , Moving screen to different navigator

Viewed 1733

still try to understand about multiple navigator here.

Basically i have 2 navigator, one rootnavigator for login page, and the appnavigator for any screen after login, below is the app.js

import * as React from 'react';
import { Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import LoginScreen from './src/pages/auth/Login';
import HomeScreen from './src/pages/auth/Home';
import MemoryScreen from './src/pages/games/Memory';

const AppStack = createStackNavigator();
const RootStack = createStackNavigator();

function HomeNavigator() {
  return (
    <AppStack.Navigator mode="modal" initialRouteName="Login" screenOptions={({ route, navigation }) => ({
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerRight: () => (
        <Button
          onPress={() => navigation.navigate('Login')}
          title="Logout"
          color="#fff"
        />
      ),
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    })}>
      <AppStack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          title: 'Simple Scorecard',
        }}
      />
      <AppStack.Screen
        name="Memory"
        component={MemoryScreen}
        options={{
          title: 'Memory Games',
        }} />
    </AppStack.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <RootStack.Navigator initialRouteName="Login">
        <RootStack.Screen
          name="Login"
          component={LoginScreen}
          options={{
            title: 'Simple Scorecard',
          }} />
        <RootStack.Screen name="App" component={HomeNavigator} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
}

From login page i try to move to home screen like below . (Login.js)

import React, { Component } from 'react';
import { Button, TextInput, View, StyleSheet } from 'react-native';

export default class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: '',
        };
    }

    onLogin({ navigation }) {
        const { username, password } = this.state;
        // navigation.navigate('HomeNavigator', {
        //     screen: 'Home',
        //   })
        this.props.navigation.navigate('HomeNavigator', {
            screen: 'Home',
          })
    }

    render() {
        return (
            <View style={styles.container}>
                <TextInput
                    value={this.state.username}
                    onChangeText={(username) => this.setState({ username })}
                    placeholder={'Username'}
                    style={styles.input}
                />
                <TextInput
                    value={this.state.password}
                    onChangeText={(password) => this.setState({ password })}
                    placeholder={'Password'}
                    secureTextEntry={true}
                    style={styles.input}
                />

                <Button
                    title={'Login'}
                    style={styles.input}
                    onPress={this.onLogin.bind(this)}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#ecf0f1',
    },
    input: {
        width: 200,
        height: 44,
        padding: 10,
        borderWidth: 1,
        borderColor: 'black',
        marginBottom: 10,
    },
});

Problem is, i can't navigate to home page, error notice below :

The action 'NAVIGATE' with payload {"name":"HomeNavigator","params":{"screen":"Home"}} was not handled by any navigator.

Do you have a screen named 'HomeNavigator'?

May i know how to solve this? Thanks

2 Answers

Yes I think you understand Nesting navigators but A litter bit mistake is call wrong name of HomeNavigator I think right must be

       this.props.navigation.navigate('App', {
            screen: 'Home',
          })

Because "App" is name of screen you assign in container

export default function App() {
  return (
    <NavigationContainer>
      <RootStack.Navigator initialRouteName="Login">
        <RootStack.Screen
          name="Login"
          component={LoginScreen}
          options={{
            title: 'Simple Scorecard',
          }} />
        <RootStack.Screen name="App" component={HomeNavigator} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
}

Understand more in here https://reactnavigation.org/docs/nesting-navigators/

Replace this line

 onLogin({ navigation }) {
    const { username, password } = this.state;
    // navigation.navigate('HomeNavigator', {
    //     screen: 'Home',
    //   })
    this.props.navigation.navigate('HomeNavigator', {
        screen: 'Home',
      })
}

by

 onLogin({ navigation }) {
    const { username, password } = this.state;
    // navigation.navigate('HomeNavigator', {
    //     screen: 'Home',
    //   })
    this.props.navigation.navigate('App', {
        screen: 'Home',
      })
}

OR you can do vice versa:- change

 <RootStack.Screen name="App" component={HomeNavigator} />

to this

 <RootStack.Screen name="HomeNavigator" component={HomeNavigator} />

You call it by what is in name, not in component.

But I will recommend you to see this example because that can be optimal way to switch before and after login.

Hope it helps!!!

Related