bottom tabs not on all screens despite being nested - react-native

export default function Navigation({ colorScheme }: { colorScheme:
ColorSchemeName }) {
return (
<NavigationContainer
linking= {LinkingConfiguration}
theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<RootNavigator />
</NavigationContainer> ); }
function RootNavigator() {
return (
<Stack.Navigator screenOptions={{
headerShown: false}}
>
<Stack.Screen name="Root" component={BottomTabNavigator} options={{ headerShown: false
}} />
<Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }}
/>
<Stack.Group screenOptions={{ presentation: 'fullScreenModal' }}>
<Stack.Screen name="Modal" component={ModalScreen} />
<Stack.Screen name="Paywall1" component={Paywall1Screen} />
<Stack.Screen name="Paywall" component={PaywallScreen} />
<Stack.Screen name="WelcomeScreen" component={WelcomeScreen} />
</Stack.Group>
</Stack.Navigator>
);
}
const BottomTab = createBottomTabNavigator<RootTabParamList>();
function BottomTabNavigator() {
const colorScheme = useColorScheme();
return (
<BottomTab.Navigator
initialRouteName="HomeScreen"
screenOptions={{
headerShown: false,
tabBarActiveTintColor: Colors[colorScheme].tint,
}}>
<BottomTab.Screen
name="HomeScreen"
component={HomeScreen}
options={{
tabBarLabel: 'Today',
tabBarIcon: ({ color }) => <TabBarIcon name="home" color=
{color} />,
}}
/>
<BottomTab.Screen
name="Episodes"
component={EpisodesScreen}
options={{
title: 'Episodes',
tabBarIcon: ({ color }) => <TabBarFeatherIcon
name="headphones" color={color} />,
}}
/>
<BottomTab.Screen
name="TabThree"
component={TabThreeScreen}
options={{
title: 'Guides',
tabBarIcon: ({ color }) => <TabBarFeatherIcon name="bookmark" color={color} />,
}}
/>
<BottomTab.Screen
name="CommunityScreen"
component={CommunityScreen}
options={{
title: 'Community',
tabBarIcon: ({ color }) => <TabBarIcon name="users" color=
{color} />,
}}
/>
<BottomTab.Screen
name="ProfileScreen"
component={ProfileScreen}
options={{
title: 'Profile',
tabBarIcon: ({ color }) => <TabBarIcon name="user" color=
{color} />,
}}
/>
</BottomTab.Navigator>
);
}
Using EXPO version 43.0.1 with react-navigation/core 6.1.0 react-navigation/bottom-tabs 6.0.9
I need the bottomTabNavigator to show on all screens and not just the 5 i have listed in my bottomTabNavigator. nothing on here seems to help with this just the opposite of keeping them off the screens the user doesnt want them on.
For example if i'm on my Paywall screen i do not see my bottomTabs (this route is not included in the bottomTabNavigator)

At the current moment in your question you do not mention what version or the entire file for the component RootNavigator. At glance, if you're using React Navigation 6 it needs a NavigationContainer and I don't see that in your question, example with NavigationContainer:
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack'
const Stack = createNativeStackNavigator()
const RootNavigator = () => {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name='Root' component={BottomTabNavigator} options={{ headerShown: false }} />
<Stack.Screen name='NotFound' component={NotFoundScreen} options={{ title: 'Oops!' }} />
<Stack.Group screenOptions={{ presentation: 'fullScreenModal' }}>
<Stack.Screen name='Modal' component={ModalScreen} />
<Stack.Screen name='Paywall1' component={Paywall1Screen} />
<Stack.Screen name='Paywall' component={PaywallScreen} />
<Stack.Screen name='WelcomeScreen' component={WelcomeScreen} />
</Stack.Group>
</Stack.Navigator>
</NavigationContainer>
)
}
export default RootNavigator

Related

What's the correct approach for having a list/detail view with React Native Navigation Bottom Tab?

I have something like:
const Tab = createBottomTabNavigator<DefaultTabbedParamList>();
const DefaultTabbedNavigation = () => {
return (
<>
<Tab.Navigator initialRouteName='Home' screenOptions={{
unmountOnBlur: true,
}}>
<Tab.Screen name="Home" component={HomeScreen} options={{
...defaultOptions,
tabBarIcon: ({ color, size, focused }) => (
<Icon as={Ionicons} name={`home${focused ? `` : `-outline`}`} size={size} color={color} />
)
}} />
...
</Tab.Navigator>
</>
);
}
When a user clicks to a detail view from Home (or any other tab), I want to load a detail view with the currently selected tab remaining.
What's the correct approach to handle this?
One idea I had was to have a StackNavigator in HomeScreen that includes a Detail screen. But it seems repetitive to do for every screen, no?
You can do something like this :-
<Tab.Navigator initialRouteName='Home' screenOptions={{
unmountOnBlur: true,
}}>
<Tab.Screen name="Home" component={HomeScreen} options={{
...defaultOptions,
tabBarIcon: ({ color, size, focused }) => (
<Icon as={Ionicons} name={`home${focused ? `` : `-outline`}`} size={size} color={color} />
)
}} />
// Something like this.
<Tab.Screen name="Home2" children={({route}) => <route?.name />} ...{otherProperties}/>
...
</Tab.Navigator>
Note:- To use this kind of approch your routeName and componentName should be same.
How about this?
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name={"Tabs"} component={Tabs} />
<Stack.Screen name={"Detail"} component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
Yeah, you'll likely want to define a StackNavigator for each tab. It's a bit repetitive, but that's been a theme of my experience with RN.
You can do something like:
const HomeStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
);
};
const OtherStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Other" component={OtherScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
);
};
const DefaultTabbedNavigation = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackNavigator} />
<Tab.Screen name="Other" component={OtherStackNavigator} />
</Tab.Navigator>
)
}

How to hide top navigation bar in react native

I need to hide nav bar on top in specific screens. How to achieve?. i am using react-navigation/material-top-tabs
I need to hide nav bar on top in specific screens. How to achieve?. i am using react-navigation/material-top-tabs
I need to hide nav bar on top in specific screens. How to achieve?. i am using react-navigation/material-top-tabs
//page 1 <Stack.Navigator headerMode="none" initialRouteName="Connection">
<Stack.Screen
name="Connection"
component={UserScreen}
options={{ unmountOnBlur: true }}
/>
</Stack.Navigator>
//page2 <Tab.Navigator
// screenOptions={{ tabBarVisible: false }}
// screenOptions={({ route }) => ({
// tabBarVisible: false,
// })}
initialRouteName="UserTabStack"
tabBarOptions={{
labelStyle: {
fontWeight: "bold",
},
indicatorStyle: {
backgroundColor: "black",
},
}}
>
<Tab.Screen
name="UserTabStack"
// component={UserList}
component={UserTabStack}
options={{ tabBarLabel: "Userlist" }}
listeners={({ route }) => {
setTabPage(route.name);
}}
/>
<Tab.Screen
name="GroupList"
// component={GroupList}
component={GroupTabStack}
options={{ tabBarLabel: "GroupList" }}
listeners={({ route }) => {
setTabPage(route.name);
}}
/>
</Tab.Navigator> //page3 <Stack.Navigator headerMode="none" initialRouteName="UserList">
<Stack.Screen
name="UserList"
component={UserList}
options={{ unmountOnBlur: true }}
/>
<Stack.Screen
name="AddConnection"
component={AddUserScreen}
options={{ unmountOnBlur: true }}
/>
<Stack.Screen
name="Chat"
component={ChatScreen}
options={{ unmountOnBlur: true }}
/>
</Stack.Navigator>
set headerShown to false in Stack.Screen options
<Stack.Screen
name="UserList"
component={UserList}
options={{ unmountOnBlur: true, headerShown: false }}
/>
Per the React Navigation Docs, you can hide the tab bar on specific screens by changing your navigation structure. In their example:
function HomeTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Notifications" component={Notifications} />
</Tab.Navigator>
);
}
function App() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeTabs} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
);
}
The tab navigator is inside the first screen, and is the first component in your app's navigator. The following components are the two components that you don't want the top bar to be shown on, so in this example, Settings and Profile.

React Native how to programmatically navigate to a stack screen that is on a tab navigator

I have searched tirelessly for an answer to this issue.
I have a Tab Navigator:
const AppNavigator = () => {
return (
<Tab.Navigator initialRouteName="Search">
<Tab.Screen
name="Home"
children={() => <HomeScreen />}
options={{
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Search"
children={() => <SearchContainerNavigator />}
options={{
tabBarIcon: ({ color, size }) => (
<FontAwesome5 name="search" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Feedback"
children={() => <FeedbackScreen />}
options={{
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="email" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
};
And this Stack navigator:
const SearchContainerNavigator = () => (
<Stack.Navigator screenOptions={{ headerShown: false}} initialRouteName="SearchSelect">
<Stack.Screen name="SearchSelect" component={SearchSelectScreen} />
<Stack.Screen name="AircraftSearch" component={AircraftSearchScreen} />
<Stack.Screen name="AircraftResults" component={AircraftResultsScreen} />
<Stack.Screen name="AircraftDetail" component={AircraftDetailScreen} />
<Stack.Screen name="BrandSearch" component={BrandSearchScreen} />
<Stack.Screen name="BrandResults" component={BrandResultsScreen} />
<Stack.Screen name="BrandDetail" component={BrandDetailScreen} />
<Stack.Screen name="Favourites" component={FavouritesScreen} />
</Stack.Navigator>
)
My issue is how do I programmatically navigate from HomeScreen tab to the AircraftDetailsScreen on the Search Tab??
Thanks in advance.
EDIT:
HomeScreen is a class.
handleAircraftSelect = (aircraft_id) => {
this.props.navigation.navigate("Search", {
screen: "AircraftDetail",
params: { id: aircraft_id },
});
};
navigation.navigate('Search', {screen: 'AircraftDetail'});
https://reactnavigation.org/docs/nesting-navigators/#navigating-to-a-screen-in-a-nested-navigator
For react-navigation 6.x you can use this like below:
navigation.jumpTo('Profile', { name: 'Michaƛ' });

How to put the title of screens in header of each screen?

I need a hand to understand the behavior of my screens on my application.
I just noticed that, whatever screen I'm browsing, the title of the screen at the top of the header is always "Orders".
Of course, I want each header to display the screen title, so I think there is some information missing in my navigation file.
However, I don't really know where or how to add the title of the screen in the header.
However, I put the name/title of the screen in each Stack. screen.
Could you guide me, help me and explain to me where is my mistake, please?
Thank you for reading me.
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const screenOptionStyle = {
headerStyle: {
backgroundColor: "#F78400",
},
headerTintColor: "white",
headerBackTitle: "Back",
backgroundColor:'#f7f6f6'
};
export const MainStackNavigator = () => {
return (
<Stack.Navigator screenOptions={screenOptionStyle}>
<Stack.Screen name = 'Orders' component = {BottomTabNavigator} options={{ title: i18n.t("orders.title") }}/>
<Stack.Screen name = 'Authentication' component = {Authentication} options={{title: i18n.t("authentication.title"), headerShown: false }}/>
<Stack.Screen name = 'Account' component = {Account} options={{ title: i18n.t("account.title") }}/>
<Stack.Screen name = 'Activities' component = {Activities} options={{ title: i18n.t("activities.title") }}/>
<Stack.Screen name = 'Contact' component = {Contact} options={{ title: i18n.t("contact.title") }}/>
<Stack.Screen name = 'Login' component = {Login} options={{ title: i18n.t("login.title"), headerShown: false }}/>
<Stack.Screen name = 'Register' component = {Register} options={{ title: i18n.t("register.title"), headerShown: false }}/>
<Stack.Screen name = 'Reset' component = {Reset} options={{ title: i18n.t("reset.title") }}/>
<Stack.Screen name = 'Tools' component = {Tools} options={{ title: i18n.t("tools.title") }}/>
<Stack.Screen name = 'Scan' component = {Scan} options={{ title: i18n.t("scan.title") }}/>
<Stack.Screen name = 'Current' component = {Current} options={{ title: i18n.t("current.title") }}/>
<Stack.Screen name = 'Completed' component = {Completed} options={{ title: i18n.t("completed.title") }}/>
<Stack.Screen name = 'Products' component = {Products} options={{ title: i18n.t("products.title") }}/>
<Stack.Screen name = 'ProductDetails' component = {ProductDetails} options={{ title: i18n.t("fiche.title") }}/>
<Stack.Screen name = 'Information' component = {Information} options={{ title: i18n.t("information.title") }}/>
<Stack.Screen name = 'Photos' component = {Photos} options={{ title: i18n.t("photos.title") }}/>
<Stack.Screen name = 'Stock' component = {Stock} options={{ title: i18n.t("stock.title") }}/>
<Stack.Screen name = 'Terms' component = {Terms} options={{ title: i18n.t("terms.title") }}/>
<Stack.Screen name = 'About' component = {About} options={{ title: i18n.t("about.title") }}/>
<Stack.Screen name = 'Tickets' component = {Tickets} options={{ title: i18n.t("tickets.title") }}/>
<Stack.Screen name = 'Dashboard' component = {Dashboard} options={{ title: i18n.t("dashboard.title") }}/>
<Stack.Screen name = 'Settings' component = {Settings} options={{ title: i18n.t("settings.title") }}/>
<Stack.Screen name = 'Welcome' component = {Welcome} options={{ title: i18n.t("welcome.title") }}/>
<Stack.Screen name = 'BottomTabNavigator' component = {BottomTabNavigator} options={{ title: i18n.t("welcome.title") }}/>
</Stack.Navigator>
);
}
export const BottomTabNavigator = () => {
return (
<Tab.Navigator tabBarOptions={{
activeTintColor: 'black',
labelStyle: {fontSize: 12, color: 'white'},
style: {backgroundColor: '#F78400'},
}}>
<Tab.Screen
name={i18n.t("orders.title")}
component={Orders}
options={{
tabBarIcon: ({ focused, horizontal, tintColor }) => {
return (
<Image
source={require("../assets/images/orders.png")}
style={styles.icon}
/>
);
}
}}
/>
<Tab.Screen
name={i18n.t("dashboard.title")}
component={Dashboard}
options={{
tabBarIcon: ({ focused, horizontal, tintColor }) => {
return (
<Image
source={require("../assets/images/dashboard.png")}
style={styles.icon}
/>
);
}
}}
/>
<Tab.Screen
name={i18n.t("tools.title")}
component={Tools}
options={{
tabBarIcon: ({ focused, horizontal, tintColor }) => {
return (
<Image
source={require("../assets/images/tools.png")}
style={styles.icon}
/>
);
}
}}
/>
<Tab.Screen
name={i18n.t("settings.title")}
component={Settings}
options={{
tabBarIcon: ({ focused, horizontal, tintColor }) => {
return (
<Image
source={require("../assets/images/settings.png")}
style={styles.icon}
/>
);
}
}}
/>
</Tab.Navigator>
);
};
Since you have nested BottomTabNavigation in stack screen. Title of the stack screen will always be same.
import {getFocusedRouteNameFromRoute} from '#react-navigation/native';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const screenOptionStyle = {
headerStyle: {
backgroundColor: '#F78400',
},
headerTintColor: 'white',
headerBackTitle: 'Back',
backgroundColor: '#f7f6f6',
};
function getHeaderTitle(route) {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'OrdersTab';
switch (routeName) {
case 'OrdersTab':
return i18n.t('orders.title');
case 'DashboardTab':
return i18n.t('dashboard.title');
case 'ToolsTab':
return i18n.t('tools.title');
case 'SettingsTab':
return i18n.t('settings.title');
}
}
export const MainStackNavigator = () => {
return (
<Stack.Navigator screenOptions={screenOptionStyle}>
<Stack.Screen
name="Orders"
component={BottomTabNavigator}
options={({route}) => ({
headerTitle: getHeaderTitle(route),
})}
/>
<Stack.Screen
name="Authentication"
component={Authentication}
options={{title: i18n.t('authentication.title'), headerShown: false}}
/>
<Stack.Screen
name="Account"
component={Account}
options={{title: i18n.t('account.title')}}
/>
<Stack.Screen
name="Activities"
component={Activities}
options={{title: i18n.t('activities.title')}}
/>
<Stack.Screen
name="Contact"
component={Contact}
options={{title: i18n.t('contact.title')}}
/>
<Stack.Screen
name="Login"
component={Login}
options={{title: i18n.t('login.title'), headerShown: false}}
/>
<Stack.Screen
name="Register"
component={Register}
options={{title: i18n.t('register.title'), headerShown: false}}
/>
<Stack.Screen
name="Reset"
component={Reset}
options={{title: i18n.t('reset.title')}}
/>
<Stack.Screen
name="Tools"
component={Tools}
options={{title: i18n.t('tools.title')}}
/>
<Stack.Screen
name="Scan"
component={Scan}
options={{title: i18n.t('scan.title')}}
/>
<Stack.Screen
name="Current"
component={Current}
options={{title: i18n.t('current.title')}}
/>
<Stack.Screen
name="Completed"
component={Completed}
options={{title: i18n.t('completed.title')}}
/>
<Stack.Screen
name="Products"
component={Products}
options={{title: i18n.t('products.title')}}
/>
<Stack.Screen
name="ProductDetails"
component={ProductDetails}
options={{title: i18n.t('fiche.title')}}
/>
<Stack.Screen
name="Information"
component={Information}
options={{title: i18n.t('information.title')}}
/>
<Stack.Screen
name="Photos"
component={Photos}
options={{title: i18n.t('photos.title')}}
/>
<Stack.Screen
name="Stock"
component={Stock}
options={{title: i18n.t('stock.title')}}
/>
<Stack.Screen
name="Terms"
component={Terms}
options={{title: i18n.t('terms.title')}}
/>
<Stack.Screen
name="About"
component={About}
options={{title: i18n.t('about.title')}}
/>
<Stack.Screen
name="Tickets"
component={Tickets}
options={{title: i18n.t('tickets.title')}}
/>
<Stack.Screen
name="Dashboard"
component={Dashboard}
options={{title: i18n.t('dashboard.title')}}
/>
<Stack.Screen
name="Settings"
component={Settings}
options={{title: i18n.t('settings.title')}}
/>
<Stack.Screen
name="Welcome"
component={Welcome}
options={{title: i18n.t('welcome.title')}}
/>
<Stack.Screen
name="BottomTabNavigator"
component={BottomTabNavigator}
options={{title: i18n.t('welcome.title')}}
/>
</Stack.Navigator>
);
};
export const BottomTabNavigator = () => {
return (
<Tab.Navigator
tabBarOptions={{
activeTintColor: 'black',
labelStyle: {fontSize: 12, color: 'white'},
style: {backgroundColor: '#F78400'},
}}>
<Tab.Screen
name={'OrdersTab'}
component={Orders}
options={{
tabBarIcon: ({focused, horizontal, tintColor}) => {
return (
<Image
source={require('../assets/images/orders.png')}
style={styles.icon}
/>
);
},
}}
/>
<Tab.Screen
name={'DashboardTab'}
component={Dashboard}
options={{
tabBarIcon: ({focused, horizontal, tintColor}) => {
return (
<Image
source={require('../assets/images/dashboard.png')}
style={styles.icon}
/>
);
},
}}
/>
<Tab.Screen
name={'ToolsTab'}
component={Tools}
options={{
tabBarIcon: ({focused, horizontal, tintColor}) => {
return (
<Image
source={require('../assets/images/tools.png')}
style={styles.icon}
/>
);
},
}}
/>
<Tab.Screen
name={'SettingsTab'}
component={Settings}
options={{
tabBarIcon: ({focused, horizontal, tintColor}) => {
return (
<Image
source={require('../assets/images/settings.png')}
style={styles.icon}
/>
);
},
}}
/>
</Tab.Navigator>
);
};

Hide Custom Header in specific screen with headerMode float

I have 3 screen in my app: "Home, Contacts, Profile". I created a custom header to show in Home and Contacts, but not in Profile screen. The problem is: my custom header don't hide in Profile Screen. If I remove my custm header to use the default header, it hides, but when I back to my custom header this doesn't happen.
App.js
<NavigationContainer ref={navigationRef}>
<Stack.Navigator
headerMode="float"
initialRouteName="Home"
screenOptions={{
header: props => <CustomHeader {...props} />
}}>
<Stack.Screen
name="Home"
component={Home}
options={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS
}}/>
<Stack.Screen name="Contacts" component={Contacts}
options={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS
}}/>
<Stack.Screen
name="Profile"
component={Profile}
options={{
headerShown: false
}} />
</Stack.Navigator>
</NavigationContainer>
You can provide screen wise header like.
<NavigationContainer ref={navigationRef}>
<Stack.Navigator
headerMode="float"
initialRouteName="Home">
<Stack.Screen
name="Home"
component={Home}
options={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
header: (props) => <CustomHeader {...props} />
}}
/>
<Stack.Screen
name="Contacts"
component={Contacts}
options={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
header: (props) => <CustomHeader {...props} />
}}
/>
<Stack.Screen
name="Profile"
component={Profile}
options={{
headerShown: false,
header: null,
}}
/>
</Stack.Navigator>
</NavigationContainer>;
Or you can create custom function for all header
function getHeader(route, props) {
const routeName = route.state
?
route.state.routes[route.state.index].name
: || 'Home';
switch (routeName) {
case 'Home':
case 'Contacts':
return <CustomHeader {...props} />
case 'Profile':
return null;
}
}
and use it like
<Stack.Screen
name="Profile"
component={Profile}
options={({ route }) => ({
header: (props)=> getHeader(route, props),
})}
/>
Source : https://reactnavigation.org/docs/screen-options-resolution