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:
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",
},
});
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.