React Native: Different headers for different screens in Stack Navigator - react-native

I am using #react-navigation/stack version ^5.5.1. I am trying to have different headers on different screens in my Stack Navigation. For example, on Master, I want no header, i.e., headerMode="none"; on Home, I want a custom header, and on Details I want a different custom header. How do I achieve this? This is my current code:
const AppStack = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Master" component={ Master } />
<Stack.Screen name="Home" component={ Home } />
<Stack.Screen name="Details" component={ Details } />
</Stack.Navigator>
</NavigationContainer>
)
}

I just figured it out.
First, put headerMode="screen" on the Stack.Navigator. This moves control of the header to each screen. Then use the syntax as shown below for each individual screen.
const AppStack = () => {
return (
<NavigationContainer>
<Stack.Navigator headerMode="screen">
<Stack.Screen name="Master" component={ Master } options={{ headerShown: false }} />
<Stack.Screen name="Home" component={ Home } options={{ headerTitle: props => <MyCustomHeader {...props} /> }}/>
<Stack.Screen name="Details" component={ Details } options={{ headerTitle: props => <MyOtherCustomHeader {...props} /> }}/>
</Stack.Navigator>
</NavigationContainer>
)
}

Related

React Navigation - Drawer inside Stack go back

Taking this example for the official documentation :
function Root() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Root"
component={Root}
options={{ headerShown: false }}
/>
<Stack.Screen name="Feed" component={Feed} />
</Stack.Navigator>
</NavigationContainer>
);
}
They just explain here how to navigate to the Profile screen from the Feed screen like this :
navigation.navigate('Root', { screen: 'Profile' });
I would to know how can I navigate to the Feed screen from the Profile screen;
You can just use the navigation object and its navigate function since the Feed screen is nested inside the same navigator as the Root stack.
Destructure the navigation object from the props of Profile.
function Profile({navigation}) {
return ...
}
Now, just use the navigation object as follows in order to navigate to Feed.
navigation.navigate("Feed")

How can I a nested navigation for my react native app

I have my App stack with Tab navigation and I want to add some more screens to my settings page below is my App.js page how can I do it
App.js
I need to add to make a SettingsStack for this below page
Settings.js
Create a function (for eg: 'TabNavigation') which returns tab navigator component then try putting tab navigator inside stack like below example
import Profile from '../screens/settings/Profile';
import ManageRooms from '../screens/settings/ManageRooms';
....
const TabNavigation = () => {
<Tab.Navigator
.....
</<Tab.Navigator>
}
....
<NavigationContainer>
{authState.isAuthenticated ? (
<Stack.Navigator
initialRouteName="Tabs"
screenOptions={{
headerShown: false,
}}>
<Stack.Screen name="Tabs" component={TabNavigation} />
<Stack.Screen
key={'Profile'}
name={'Profile'}
component={Profile}
/>
<Stack.Screen
key={'ManageRooms'}
name={'ManageRooms'}
component={ManageRooms}
/>
</Stack.Navigator>) : (
<Stack.Navigator
screenOptions={{
header: () => {},
}}>
<Stack.Screen name="SignIn" component={SignIn} />
<Stack.Screen name="SignUp" component={SignUp} />
</Stack.Navigator>
)}
</NavigationContainer>
....

react native navigation between screens

I'm trying to use reactnavigation.org library and I have some issue with that. I have two types of navigation screens. Two screens are a registration and authorization. And others are regular app screens. Problem is that I can't render parent component App.js or other functionality to reload app from child component and thus change my screens block. Navigation between screens Run, History, Profile, OtherRunners works fine. Navigation between screens Main and Enter works fine. But if I need navigate from Run to Main, or from Enter to Run there is a problem.
App.js
const App = () => {
const Stack = createStackNavigator()
const Drawer = createDrawerNavigator()
const [loggedIn, setLoggedIn] = useState(false)
async function getUserEmail(){
if(await AsyncStorage.getItem('#email')){
setLoggedIn(true)
}else{
setLoggedIn(false)
}
}
getUserEmail()
function MenuDraw(){
return(
<Drawer.Navigator
drawerContentOptions={}
drawerType={}
drawerStyle={{}}
>
<Drawer.Screen
name="Run"
component={Run}
options={}
/>
<Drawer.Screen
name="History"
component={History}
options={}
/>
<Drawer.Screen
name="Profile"
component={Profile}
options={}
/>
<Drawer.Screen
name="OtherRunners"
component={OtherRunners}
options={}
/>
<Drawer.Screen
name="LogOut"
component={Run}
initialParams={{action: 'logout'}}
options={}
/>
</Drawer.Navigator>
)
}
function MyDrawer(){
if(loggedIn){
return(
<Stack.Navigator
screenOptions={{headerShown: false}}
initialRouteName={"MenuDraw"}
>
<Stack.Screen name="MenuDraw" component={MenuDraw}/>
<Stack.Screen name="Details" component={Details}/>
</Stack.Navigator>
)
}else{
return (
<Stack.Navigator
screenOptions={{headerShown: false}}
initialRouteName={"Main"}
>
<Stack.Screen name="MenuDraw" component={MenuDraw} />
<Stack.Screen name="Details" component={Details} />
<Stack.Screen name="Main" component={Main} />
<Stack.Screen name="Enter" component={Enter} />
</Stack.Navigator>
)
}
}
return(
<NavigationContainer>
<MyDrawer/>
</NavigationContainer>
)
}
export default App;
I tried using reload app tools, but those wasn't help me. They are wasn't working. In this section of code which is below. On the Run screen.
Run.js
const Run = ({navigation,route}) => {
const clearStorage = async () => {
await AsyncStorage.clear()
}
if(route.params){
if(route.params.action === 'logout'){
clearStorage()
navigation.navigate("Main", {})
}
}
}
export default Run;
I'm trying to logout by cleaning the storage and navigate to Main screen. But it's not working on release mode. I've tried this, which is below.
App.js
function MyDrawer(){
if(loggedIn){
return(
<Stack.Navigator
screenOptions={{headerShown: false}}
initialRouteName={"MenuDraw"}
>
<Stack.Screen name="MenuDraw" component={MenuDraw}/>
<Stack.Screen name="Details" component={Details}/>
++++ <Stack.Screen name="Main" component={Main} />
++++ <Stack.Screen name="Enter" component={Enter} />
</Stack.Navigator>
)
}else{
return (
<Stack.Navigator
screenOptions={{headerShown: false}}
initialRouteName={"Main"}
>
<Stack.Screen name="MenuDraw" component={MenuDraw} />
<Stack.Screen name="Details" component={Details} />
<Stack.Screen name="Main" component={Main} />
<Stack.Screen name="Enter" component={Enter} />
</Stack.Navigator>
)
}
}
Not working either way. How can I fix it? Can I render App.js component from child screens? Or perhaps I should create two screen blocks line
<Stack.Screen name="MenuDraw" component={MenuDraw}/>
<Stack.Screen name="MenuRegister" component={MenuRegister}/>
and put all my screens by belongings to match section?
I need to logout from this section:
App.js
some code
<Drawer.Screen
name="LogOut"
component={Run}
initialParams={{action: 'logout'}}
options={}
/>
</Drawer.Navigator>
some code
Did you try using useEffect hook, to get on the road? :-)
useEffect(() => {
const getUserEmail = async () => {
if(await AsyncStorage.getItem('#email')){
setLoggedIn(true)
}else{
setLoggedIn(false)
}
};
getUserEmail();
}, []);

Tab navigator adding header

I am using React navigation. I want to add headers to my tab navigator components. How can I do that?
Tab navigation function
const TabNavigation = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Welcome} />
<Tab.Screen name="Favorites" component={Favorites} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
);
};
Stack navigator function
<Stack.Navigator
initialRouteName="SignIn">
<Stack.Screen name="SignIn" component={SignIn} />
<Stack.Screen name="TabNavigation" component={TabNavigation}/>
<Stack.Navigator>
You can customize your header dynamically in Stack Navigation screen options prop. For example you can create custom functions like getTitle to determine title dynamically depending on your route.
<Stack.Screen
name="TabNavigation"
component={TabNavigation}
options={({ route }) => ({
//title: getTitle(route),
//headerStyle: styles.headerStyle
//headerTitleStyle: styles.headerTitleStyle
})}
/>

ReactNative- Tab Navigator Inside Stack Navigator

Need to Show Tabs For Home Module after Signup Module
using React-navigation
Working Code with Only Stack Screens
const Stack = createStackNavigator();
const Bottom = createBottomTabNavigator();
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Welcome" headerMode='none' >
<Stack.Screen name="Welcome" component={WelcomeScreen}
options={{
title: '',
headerBackTitleVisible: false,
headerBackTitle: '',
headerShown: true
}}
/>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignupScreen} />
<Stack.Screen name="ResetPassword" component={ResetPasswordScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Need to show Tab from SigninScreen Button
Tab 1: Dashboard:
Tab 2: Profile
Tried Code:
<Bottom.Navigator initialRouteName="Dashboard" >
<Bottom.Screen name="Dashboard" component={TabDashboard} />
<Bottom.Screen name="Profile" component={TabProfile} />
</Bottom.Navigator>
Now I need to combine these two block of codes so I can navigate to Tabs
Tab screen will have further navigations
The idea would be to wrap the tabs screen inside component and add it to the stack conditionally.
const HomeScreen = () =>{
return (
<Bottom.Navigator initialRouteName="Dashboard" >
<Bottom.Screen name="Dashboard" component={TabDashboard} />
<Bottom.Screen name="Profile" component={TabProfile} />
</Bottom.Navigator>
);
}
Your stack should change as below
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Welcome" headerMode='none' >
{
this.state.isSignedIn ? (
<>
<Stack.Screen name="Welcome" component={WelcomeScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignupScreen} />
<Stack.Screen name="ResetPassword" component={ResetPasswordScreen} />
</>
) : (
<>
<Stack.Screen name="ResetPassword" component={HomeScreen} />
</>
)
}
</Stack.Navigator>
</NavigationContainer>
);
}
IsSignedIn can be the state variable or a variable that you store the logged in status
You can refer the authentication flows
https://reactnavigation.org/docs/auth-flow