id | title | sidebar_label |
---|---|---|
bottom-tab-navigator |
Bottom Tabs Navigator |
Bottom Tabs |
A simple tab bar on the bottom of the screen that lets you switch between different routes. Routes are lazily initialized -- their screen components are not mounted until they are first focused.
To use this navigator, ensure that you have @react-navigation/native
and its dependencies (follow this guide), then install @react-navigation/bottom-tabs
:
npm install @react-navigation/bottom-tabs@^5.x
To use this tab navigator, import it from @react-navigation/bottom-tabs
:
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
For a complete usage guide please visit Tab Navigation
The Tab.Navigator
component accepts following props:
The name of the route to render on first load of the navigator.
Default options to use for the screens in the navigator.
How the going back behaves in the navigator, e.g. when goBack
is called or device back button is pressed.
initialRoute
to return to initial taborder
to return to previous tab (in the order they are shown in the tab bar)history
to return to last visited tabnone
to not handle back button
Defaults to true
. If false
, all tabs are rendered immediately. When true
, tabs are rendered only when they are made active for the first time. Note: tabs are not re-rendered upon subsequent visits.
Boolean used to indicate whether inactive screens should be detached from the view hierarchy to save memory. Make sure to call enableScreens
from react-native-screens to make it work. Defaults to true
.
Style object for the component wrapping the screen content.
Function that returns a React element to display as the tab bar.
Example:
import { View, Text, TouchableOpacity } from 'react-native';
function MyTabBar({ state, descriptors, navigation }) {
const focusedOptions = descriptors[state.routes[state.index].key].options;
if (focusedOptions.tabBarVisible === false) {
return null;
}
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
}
// ...
<Tab.Navigator tabBar={props => <MyTabBar {...props} />}>
{...}
</Tab.Navigator>
This example will render a basic tab bar with labels.
Note that you cannot use the useNavigation
hook inside the tabBar
since useNavigation
is only available inside screens. You get a navigation
prop for your tabBar
which you can use instead:
function MyTabBar({ navigation }) {
return (
<Button
title="Go somewhere"
onPress={() => {
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
/>
);
}
An object containing the props for the default tab bar component. If you're using a custom tab bar, these will be passed as props to the tab bar and you can handle them.
It can contain the following properties:
Label and icon color of the active tab item.
Label and icon color of the inactive tab item.
Background color of the active tab item.
Background color of the inactive tab item.
Style object for the tab item.
Whether to show label for tab, default is true
.
Style object for the tab label text.
Whether the label is rendered below the icon or beside the icon. Possible values are:
below-icon
beside-icon
By default, in vertical
orientation (portrait mode), label is rendered below the icon and in horizontal
orientation (landscape mode)., it's rendered beside the icon.
Should the tab icons and labels alignment change based on screen size? Defaults to true
. If false
, tab icons and labels align vertically all the time (labelPosition: 'below-icon'
). When true
, tab icons and labels align horizontally on tablets (labelPosition: 'beside-icon'
).
Whether label font should scale to respect Text Size accessibility settings, default is true.
Whether the tab bar is hidden when the keyboard opens. Defaults to false
.
Safe area insets for the screen. This is used to avoid elements like notch and system navigation bar. By default, the device's safe area insets are automatically detected. You can override the behavior with this option.
Takes an object containing following optional properties:
top
- number - The value of the top inset, e.g. area containing the status bar and notch.right
- number - The value of the left inset.bottom
- number - The value of the bottom inset, e.g. area navigation bar on bottom.left
. - number - The value of the right inset.
Style object for the tab bar. You can configure styles such as background color here.
To show your screen under the tab bar, you can set the position
style to absolute:
style: {
position: 'absolute';
}
You also might need to add a bottom margin to your content if you have a absolutely positioned tab bar. React Navigation won't do it automatically.
To get the height of the bottom tab bar, you can use BottomTabBarHeightContext
with React's Context API or useBottomTabBarHeight
:
import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
// ...
<BottomTabBarHeightContext.Consumer>
{tabBarHeight => (
/* render something */
)}
</BottomTabBarHeightContext.Consumer>
or
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
// ...
const tabBarHeight = useBottomTabBarHeight();
The following options can be used to configure the screens in the navigator:
Generic title that can be used as a fallback for headerTitle
and tabBarLabel
.
true
or false
to show or hide the tab bar, if not set then defaults to true
.
Note: Hiding tab bar can cause glitches and jumpy behavior. We recommend the tab navigator inside of a stack navigator instead.
Function that given { focused: boolean, color: string, size: number }
returns a React.Node, to display in the tab bar.
Title string of a tab displayed in the tab bar or a function that given { focused: boolean, color: string }
returns a React.Node, to display in tab bar. When undefined, scene title
is used. To hide, see tabBarOptions.showLabel
in the previous section.
Text to show in a badge on the tab icon. Accepts a string
or a number
.
Style for the badge on the tab icon. You can specify a background color or text color here.
Function which returns a React element to render as the tab bar button. It wraps the icon and label and implements onPress
. Renders TouchableWithoutFeedback
by default. tabBarButton: props => <TouchableOpacity {...props} />
would use TouchableOpacity
instead.
Accessibility label for the tab button. This is read by the screen reader when the user taps the tab. It's recommended to set this if you don't have a label for the tab.
ID to locate this tab button in tests.
Whether this screen should be unmounted when navigating away from it. Unmounting a screen resets any local state in the screen as well as state of nested navigators in the screen. Defaults to false
.
Normally, we don't recommend enabling this prop as users don't expect their navigation history to be lost when switching tabs. If you enable this prop, please consider if this will actually provide a better experience for the user.
The navigator can emit events on certain actions. Supported events are:
This event is fired when the user presses the tab button for the current screen in the tab bar. By default a tab press does several things:
- If the tab is not focused, tab press will focus that tab
- If the tab is already focused:
- If the screen for the tab renders a scroll view, you can use
useScrollToTop
to scroll it to top - If the screen for the tab renders a stack navigator, a
popToTop
action is performed on the stack
- If the screen for the tab renders a scroll view, you can use
To prevent the default behavior, you can call event.preventDefault
:
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
// Do something manually
// ...
});
return unsubscribe;
}, [navigation]);
If you have a custom tab bar, make sure to emit this event.
This event is fired when the user presses the tab button for the current screen in the tab bar for an extended period. If you have a custom tab bar, make sure to emit this event.
Example:
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabLongPress', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
The tab navigator adds the following methods to the navigation prop:
Navigates to an existing screen in the tab navigator. The method accepts following arguments:
name
- string - Name of the route to jump to.params
- object - Screen params to merge into the destination route (found in the pushed screen throughroute.params
).
navigation.jumpTo('Profile', { owner: 'Michaś' });
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
tabBarOptions={{
activeTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Notifications"
component={Notifications}
options={{
tabBarLabel: 'Updates',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="bell" color={color} size={size} />
),
tabBarBadge: 3,
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="account" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}