Home > Enterprise >  Make only one Stack.Navigator show up
Make only one Stack.Navigator show up

Time:03-04

I am creating an app in ReactNative and I have two Stack Navigators inside two separate Navigation Containers, one for login/registering a user and another one that leads to from a search page to a details page.

What I want know is that when the app launches, the login page should be the first thing a user sees. However, with my two stack navigators now, this is how the mobile app looks like:

enter image description here

Here is the code from my two Stack Navigators, any insight on how I can refactor my code so that the screens are not split but rather only one stack navigator appears when the app is booted up would be much appreciated!

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Button, View, Text } from "react-native";
import Post from "./src/components/Post";
import AppContext from  "./src/components/AppContext";

import LoginScreen from "./src/screens/Login";
import RegisterScreen from "./src/screens/Register";
import SearchScreen from "./src/screens/Search";
import ShowDetailsScreen from "./src/screens/ShowDetails";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import React, { useState } from 'react';

export default function App() {
  
  const [token, setToken] = useState("");
  const userSettings = {
    token: "",
    setToken,
  };
  
  const Stack = createNativeStackNavigator();

  return (
    <AppContext.Provider value={userSettings}>
      <NavigationContainer>

      <Stack.Navigator>
        <Stack.Screen name="Login" component={LoginScreen}/>
        <Stack.Screen name="Register" component={RegisterScreen}/>
     
      </Stack.Navigator> 
      </NavigationContainer>

      <NavigationContainer>

        <Stack.Navigator>
          <Stack.Screen
            name="Search"
            component={SearchScreen}
            options={{ headerShown: false }}
          />
          <Stack.Screen name="Show Details" component={ShowDetailsScreen} />
        </Stack.Navigator>

        <StatusBar style="dark" />

      </NavigationContainer>
    </AppContext.Provider>
  );
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

CodePudding user response:

The problem with your code is that you are showing two stacks at the same time. What you need to do is that you should have some kind of way to know if a user is registered or not and depending on that to show Register screen or Search screen. Here is a good example how to do that (but you don't have to implement exactly like that. It is just for your understanding)

CodePudding user response:

I would like to suggest a different approach. Instead of creating two separate NavigationContainer and two different StackNavigator we could create a state that handles what you want.

In fact we could exploit the fact that an unsigned user does not have a token yet which is already present as a state in your application.

Consider the following.

export default function App() {
  
  const [token, setToken] = useState();
  const userSettings = {
    token: "",
    setToken,
  };
  
  const Stack = createNativeStackNavigator();

  return (
    <AppContext.Provider value={userSettings}>
      <NavigationContainer>
          <Stack.Navigator>
            
            {token ?
               <Stack.Screen name="Login" component={LoginScreen}/>
               <Stack.Screen name="Register" component={RegisterScreen}/>
               : <Stack.Screen
                  name="Search"
                  component={SearchScreen}
                  options={{ headerShown: false }}
                  />
                 <Stack.Screen name="Show Details" component={ShowDetailsScreen} />}
          </Stack.Navigator>
        <StatusBar style="dark" />
      </NavigationContainer>
    </AppContext.Provider>
  );
}

I can not see right now how you are setting the token but I guess that the state will change after a user logins. Otherwise you could create a separate isSignedIn state whose setter function will be passed as a prop to the Login screen.

This is actually recommended by react-native-navigation.

  • Related