Search code examples
react-nativereact-navigationreact-navigation-stackreact-navigation-bottom-tab

Why after login my react-navigation routing does not work properly?


I have navigation container(created in react-navigation)

const AppStack = createStackNavigator();

const AppStackScreen = () => (
        <AppStack.Navigator>
            <AppStack.Screen name="Tabbed" component={TabsScreenNavigationScreen} />
        </AppStack.Navigator>
    );

class AppNavigationContainer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            appLoading : true,
        }
    }

    user = {};

    componentDidMount() {
        let _this = this;

        this.getUser()
            .then(() => {
                this.setState({appLoading: !_this.state.appLoading})
            })
    }

    getUser = async () => {
        return await AsyncStoreService.getUserFromStore()
            .then((user) => {
                this.user = user;
            });
    }

    render() {
        const user = this.user;
        const {
            appLoading
        } = this.state;

        return (
            <NavigationContainer>
                {appLoading ?
                    <SplashScreen/>
                    :
                    <>
                        {user ?
                            <AppStackScreen/>
                            :
                            <AuthStackNavigationScreen/>
                        }
                    </>
                }
            </NavigationContainer>
        )
    }
}

export default AppNavigationContainer;

How can you see I have separated modules for app and login. login router:

const AuthStack = createStackNavigator();

const AuthStackNavigationScreen = () => (
    <AuthStack.Navigator>
        <AuthStack.Screen
            name="ChooseRole"
            component={SelectRoleScreen}
            options={{title: false}}
        />
        <AuthStack.Screen
            name="AuthStart"
            component={MainScreen}
            options={{title: false}}
        />
        <AuthStack.Screen
            name="SignIn"
            component={LoginScreen }
            options={{title: 'Sign In'}}
        />
        <AuthStack.Screen
            name="CreateAccount"
            component={RegisterScreen}
            options={{title: 'Create Account'}}
        />
    </AuthStack.Navigator>
);

export default AuthStackNavigationScreen;

Tabbed router for app:

const GalleryStack  = createStackNavigator();
const SearchStack   = createStackNavigator();
const MessagesStack = createStackNavigator();
const MenuStack     = createStackNavigator();
const Tabs          = createBottomTabNavigator();

const GalleryStackScreen = () => (
    <GalleryStack.Navigator>
        <GalleryStack.Screen name="Gallery"     component={GalleryScreen} />
        <GalleryStack.Screen name="GalleryItem" component={GalleryItemScreen} />
    </GalleryStack.Navigator>
);

const SearchStackScreen = () => (
    <SearchStack.Navigator>
        <SearchStack.Screen name="Search"        component={SearchScreen} />
        <SearchStack.Screen name="SearchResults" component={SearchResultsScreen} />
    </SearchStack.Navigator>
);

const MessagesStackScreen = () => (
    <MessagesStack.Navigator>
        <MessagesStack.Screen name="ConversationList" component={ConversationListScreen} />
        <MessagesStack.Screen name="Conversation"     component={ConversationScreen} />
    </MessagesStack.Navigator>
);

const MenuStackScreen = () => (
    <MenuStack.Navigator>
        <MenuStack.Screen name="Menu"  component={MenuScreen} />
        <MenuStack.Screen name="About" component={AboutScreen} />
    </MenuStack.Navigator>
);

const TabsScreenNavigationScreen = () => (
    <Tabs.Navigator>
        <Tabs.Screen name="Gallery"  component={GalleryStackScreen} />
        <Tabs.Screen name="Search"   component={SearchStackScreen} />
        <Tabs.Screen name="Messages" component={MessagesStackScreen} />
        <Tabs.Screen name="Menu"     component={MenuStackScreen} />
    </Tabs.Navigator>
);

export default TabsScreenNavigationScreen;

So on login screen name="SignIn" I login, perform navigation.navigate('Tabbed') after succesfully login and get message:

The action 'NAVIGATE' with payload {"name":"Tabbed"} was not handled by any navigator.

Do you have a screen named 'Tabbed'?

He doesnt 'see' my tab navigation. Why it happens so(I have such screen name and put it to render), and how can I fix this?


Solution

  • According to the stack you have you will either have the appstack or the authstack at a given moment

    <>
        {user ?
            <AppStackScreen/>
            :
            <AuthStackNavigationScreen/>
        }
    </>
    

    So you cant navigate to tabbed from signin screen which does not exist.

    The way you can handle this is update the user object maybe using a callback function or use context instead of state which will trigger a render of the AppNavigationContainer and the tabbed stack will automatically rendered instead of the auth stack. You wont need a navigate you should do the same for logout to where you will set the user to null.

    You can refer more on Auth flows