Hide title on Bottom Tabs Navigator - react-native

I'm using Bottom Tabs Navigator but it has some title that i'm not able to hide:
I saw there is tabBarShowLabel but nothing for the label particular

The tabBarShowLabel option is to specify whether or not you want to display the label inside the bottom tab with the icon.
You can use headerShown like this :
<Tab.Screen
name="Navigator"
component={YourComponent}
options={() => { // or just options={{headerShown: false}}
return {
headerShown: false,
...
),
};
}}
/>

Related

Changing navigation animation direction in react-native?

I'm currently working on a mobile application written in react-native.
This project has a number of different screens all of which are configured with createStackNavigator.
I need to be able to change the animation direction on the fly. I could be navigating to the same page on different parts of the app but require different animations. (by animation I means the direction the current screen exits the view)
I am aware options can be passed to the screen when defined to set the navigation direction. This is unfortunately no use to me as the animation may change from page to page.
Example screen declaration from my project (names have been sanitised):
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName={initialRoute}>
<Stack.Screen name="screen1" component={screen1} options={{headerShown: false, gestureEnabled: false}} />
<Stack.Screen name="screen2" component={screen2} options={{headerShown: false, gestureEnabled: false}} />
<Stack.Screen name="screen3" component={screen3} options={{headerShown: false, gestureEnabled: false}} />
<Stack.Screen name="screen4" component={screen4} options={{headerShown: false, gestureEnabled: false}} />
</Stack.Navigator>
</NavigationContainer>
Example navigation reset:
navigation.reset({
index: 0,
routes: [{ name: "screen1", params: { param1: 'paramStrData' } }]
});
Example navigation replace:
navigation.replace('screen2', { param1: 'param1StrData'})
Ideally, I'd like to be able to pass a navigation animation direction to the replace or reset functions.
Is this at all possible?
Thanks again in advance.
add props persentation , animationTypeForReplace , animation like this.
<Stack.Screen
name="screen1"
component={screen1}
options={{
headerShown: false,
presentation: 'modal',
animationTypeForReplace: 'push',
animation:'slide_from_right'
}}
/>
Pass animation,presentation and animationTypeForReplace props inside options
example.
<Stack.Screen
name="screen"
component={screen}
options={{
headerShown: false,
presentation: 'modal',
animationTypeForReplace: 'push',
animation:'slide_from_right'
}}
/>
Both answers above contributed to a solution in some way.
My understanding of the navigation stack was a little flawed at this time.
We can't dynamically change the animation type - i.e. swipe left or right.
The animation type is selected based on where the new screen is on the navigation stack or not. If already on the stack, the current screen will exit to the right and the new (previous) screen will enter from the left - this is to simulate going back.
If the new screen is not on the navigation stack, the new screen will enter from the right to simulate adding a new screen to the navigation stack.
naviagation.navigate('screenName', {param1: 'p1', param2: 'p2'})
navigate needs to be used opposed to replace to make this work.
Hope this helps someone at some point as this was something I struggled to understand for some time.

React Native - Bottom Tab Navigator - error - Passing an inline function will cause the component state to be lost on re-render?

I have a stack navigator which contains a Bottom tab navigator.
The first tab of the bottom tab navigator further contains a TopTab Navigator .
This is being done to display a Top Tab as well as a Bottom tab.
Each of the other bottom tab screens open a new screen .
Here is the code : ( stack navigator containing Bottom Tab Navigator )
const StackNav = createNativeStackNavigator();
function Main() {
return (
<NavigationContainer>
<StackNav.Navigator>
<StackNav.Screen
name="BottomTab"
component={BottomTabScreen}
options={{
headerTitle: props => <LogoTitle {...props} />,
headerBlurEffect: 'dark',
}}
/>
</StackNav.Navigator>
</NavigationContainer>
);
}
The Bottom Tab Navigator is below ( first tab contains an embedded Top Tab Navigator TopTabScreen to display header , rest of the tabs show tabs on the bottom )
const BottomTabScreen = () => {
return (
<BottomNav.Navigator barStyle={{backgroundColor: '#febe00'}}>
<BottomNav.Screen
name="Home"
component={TopTabScreen}
options={{
tabBarIcon: ({color, size}) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
labelStyle: {textTransform: 'none'},
upperCaseLabel: false,
}}
/>
<BottomNav.Screen
name="MyInitiatives"
component={InitiativesScreen}
options={{
tabBarIcon: ({color, size}) => (
<IonIcons name="rocket-outline" color={color} size={26} />
),
}}
/>
<BottomNav.Screen
name="Contact-Whatsapp"
component={() => null}
listeners={{
tabPress: (e) => {
e.preventDefault();
console.log("tabPress tabTwo");
let link = 'https://wa.me/xxx';
Linking.openURL(link);
},
}}
options={{
tabBarIcon: ({color,size}) => (
<FontAwesome name="whatsapp" color={color} size={26} />
),
}}
/>
</BottomNav.Navigator>
);
};
So on bottom tab - three tabs will show :
Home - tab which shows the embedded header
MyInitiatives - shows a separate view when clicked
Contact-Whatsapp - this is a tab which I am trying to show which when clicked should open whats
app and NOT a new screen , so on clicking the tab - I dont want any
'component' to render , rather simply whats app to open
Note - whatsapp is opening but am getting this warning :
WARN Looks like you're passing an inline function for 'component' prop for the screen
'Whatsapp'
(e.g. component={() => <SomeComponent />}). Passing an inline function will cause the
component state to be lost on re-render and cause perf issues since it's re-created every
render. You can pass the function as children to 'Screen' instead to achieve the desired
behaviour.
So questions are :
#1 how do I get around this issue ?
how do I ensure that on clicking on bottom tab - it should open the link ( in this case - whatsapp ) rather than try and open a component / view ?
The reason for the warning is that you are passing a function to the component prop rather than the name of the function. You can put any component name in there as with the e.preventDefault() it will not be opened. You can just create a small dummy component and pass in the name. Even component={View} should do the job.

How to know which Stack.Screen I'm on?

I have this Tab Screen.
<Tabs.Screen
name="Photo"
options={{
tabBarIcon: ({ focused, color, size }) => null,
}}
>
{() => <StackNavFactory screenName="Photo" />}
As you can see if I click Photo tab, It goes to 'StackNavFactory screenName=Photo'.
StackNavFactory has these two Stack screens.
It has Photo stack screen and Comments stack screen.
{screenName === "Photo" ? (
<Stack.Screen name="Photo" component={Photo} />
) : null}
<Stack.Screen
name="Comments"
component={Comments}
options={{
headerTintColor: "white",
}}
/>
Since It should go to screenName="Photo" first, when I click Photo tab, It goes to Photo Stack screen.
But if I click some button on Photo screen, I set It goes to Comments Stack screen on the same Photo tab.
In summary Photo tab has two stack screen Photo and Comments.
And I want to know where I'm on photo or Comments from TabBar components.
There are several ways to get the focused route name. In this use case, you can use the getFocusedRouteNameFromRoute(route) function.
(Untested) example:
<Tabs.Navigator
screenOptions={({ route }) => ({
tabBarStyle: {
display: getFocusedRouteNameFromRoute(route) === "..." ? "..." : "...",
},
})}
>
...
</Tabs.Navigator>
Also, you can read Setting parent screen options based on the child navigator's state in the official documentation to learn more.

How can I hide the screen header but show my back button?

I would like to hide my screen header but still show the back button in my Stack Navigator? I have set screenOptions={{ headerShown: false }} in my Stack.Navigator, which hides both the screen header and back button. I would like to just hide the screen header.
Can someone please assist with this? Below is my Stack Navigator:
function SearchStack() {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="SearchScreen" component={SearchScreen} />
<Stack.Screen name="SearchListScreen" component={SearchListScreen} />
</Stack.Navigator>
);
}
In the tab navigator the stack is set as:
<Tab.Navigator screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {...})}>
<Tab.Screen name="Search" component={SearchStack} />
</Tab.Navigator>
This is what I'm currently seeing:
But this is what I would like to have with my Tab navigation bar still at the bottom for the search stack:
This is what I get using options={{headerMode:"none"}} in Stack.Navigator:
The below occurs when adding updating the Stack.Navigator to <Stack.Navigator screenOptions={{ headerTitle:"", headerTransparent:true }}> . How can add or move the back button to the top exactly like the 2nd image, which is achieved when not adding the Stack to the Tab.Screen so changing:
<Tab.Screen name="Search" component={SearchStack} />
to
<Tab.Screen name="Search" component={SearchScreen} />
but doing this causes the tab to not appear in the Search list screen.
The back button is part of the header, so you can't hide the header and keep the back button.
What you want to do is to hide other parts of the header except for the back button, which would be
Title, with headerTitle: ""
Background, with headerTransparent: true
for hide the back button in react-native, we can use property,
headerBackVisible:false this property only work on android
<Stack.Screen
options={{headerBackVisible: false}}
/>
example use of in Stack
const CustomerStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="First"
component={First}
options={{headerShown: false}}
/>
<Stack.Screen
name="Third"
component={Third}
options={{headerTitle: '', headerTransparent: true}}
/>
</Stack.Navigator>
);
}
If you don't want the default header then use like this
screenOptions={{ headerShown: false }}
and write custom code for the header with back button in your component
(If your are using class component) Then
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> </TouchableOpacity>
if you want header title too then,
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> <Text>SearchListScren</Text> </TouchableOpacity>
Put this code at top of the component code under a container

Navigate to the screen when Tab on BottomTabNavigator is pressed

I would like to navigate to the screen when the particular tab on the BottomTabNavigator is pressed.
Normally, when the tab is pressed, it navigates to the configured screen automatically. But I don't want to have that behaviour. I want to hide the bottom tab on that screen and provide back feature in the top bar too. I normally use navigation.navigate('routeName') in ReactNavigationStack screens. But I don't know how/where to write this code in the BottomTabNavigator configuration.
For example, I've got the following 5 tabs in the bottom bar. I want to navigate to AddNewScreen when Add button is pressed. I don't know where to put that onPress event. I tried to put it under options and BottomTab.Screen. But still no luck.
I tried to intercept onPress event to use navigation.navigate. But it's not even hit and it always opens the AddNewScreen with the tab bar.
<BottomTab.Navigator initialRouteName={INITIAL_ROUTE_NAME}>
<BottomTab.Screen
name="Home"
component={HomeScreen}
initialParams="Home Params"
options={{
title: 'Home',
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name="md-home" iconType="ion" />,
}}
/>
<BottomTab.Screen
name="AddNew"
component={AddNewScreen}
options={{
title: 'Add',
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name="md-add-circle" iconType="ion"
onPress={(e) => {
e.preventDefault();
console.log(e)
}} />,
}}
/>
</BottomTab.Navigator>
The Add new screen is always opened with the bottom tab bar.
Questions:
Is there anyway to navigate to specific screen when the tab is
pressed?
Is there anyway to hide the bottom tab bar on that Add New
Screen?
Update:
The Navigation library v6 supports the Listener feature that can be used
<Tab.Screen
name="Chat"
component={Chat}
listeners={{
tabPress: e => {
// Prevent default action
e.preventDefault();
//Any custom code here
alert(123);
},
}}
/>;
You can have a custom functionality in the bottom toolbar using the tabbar button. The code would be like below
<Tab.Screen
name="Settings2"
component={SettingsScreen}
options={{
tabBarButton: props => (
<TouchableOpacity {...props} onPress={() => alert(123)} />
),
}}
/>
This would render a normal bottom tab bar button but the onclick would show the alert, you can replace the code with your navigate or any other code you need.
Also the 'SettingsScreen' component can be a dummy component returning null.
Hope this helps.
You can have a custom functionality
<Tab.Screen
name="Add"
component={View}
listeners={({ navigation }) => ({
tabPress: (e) => {
// Prevent default action
e.preventDefault();
// Do something with the `navigation` object
navigation.navigate("PhotoNavigation"); // Here!!!!!!!!!!!!!!!!!!!!!!!!!!!!
},
})}
/>
<Tab.Screen name="Notifications" component={Notifications} />