Expo 路由原生标签页
一个 Expo Router 子模块,提供原生标签页布局。
重要 Native tabs 是一个 alpha 功能,可在 SDK 54 及更高版本中使用,其 API 可能会发生变化。
expo-router/unstable-native-tabs 是 expo-router 的一个子模块,导出组件以使用平台原生系统标签来构建标签布局。
有关本地和 Web 应用的基于文件的路由库的更多信息,请参阅 Expo Router 参考资料。
安装
🌐 Installation
要在你的项目中使用 expo-router/unstable-native-tabs,你需要在项目中安装 expo-router。请按照 Expo Router 的安装指南中的说明操作:
🌐 To use expo-router/unstable-native-tabs in your project, you need to install expo-router in your project. Follow the instructions from Expo Router's installation guide:
了解如何在项目中安装 Expo Router。
应用配置中的配置
🌐 Configuration in app config
如果你使用 default 模板创建新项目,expo-router 的 配置插件 已经在你的应用配置中设置好了。
🌐 If you are using the default template to create a new project, expo-router's config plugin is already configured in your app config.
Example app.json with config plugin
{ "expo": { "plugins": ["expo-router"] } }
用法
🌐 Usage
要了解如何使用原生标签页和 Expo Router,请阅读原生标签页指南:
🌐 To learn how to use native tabs, with Expo Router, read the native tabs guide:
了解如何在你的 Expo Router 应用中使用原生标签页。
应用接口
🌐 API
import { NativeTabs } from 'expo-router/unstable-native-tabs';
Components
Type: React.Element<NativeTabsProps>
The component used to create native tabs layout.
Example
import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function Layout() { return ( <NativeTabs> <NativeTabs.Trigger name="home" /> <NativeTabs.Trigger name="settings" /> </NativeTabs> ); }
stringThe behavior when navigating back with the back button.
Acceptable values are: 'history' | 'none' | 'initialRoute'
ColorValueThe background color of every badge in the tab bar.
stringThe blur effect applied to the tab bar.
Acceptable values are: 'light' | 'dark' | 'none' | 'extraLight' | 'regular' | 'prominent' | 'systemUltraThinMaterial' | 'systemThinMaterial' | 'systemMaterial' | 'systemThickMaterial' | 'systemChromeMaterial' | 'systemUltraThinMaterialLight' | 'systemThinMaterialLight' | 'systemMaterialLight' | 'systemThickMaterialLight' | 'systemChromeMaterialLight' | 'systemUltraThinMaterialDark' | 'systemThinMaterialDark' | 'systemMaterialDark' | 'systemThickMaterialDark' | 'systemChromeMaterialDark' | 'systemDefault'
booleanWhen set to true, the tab bar will not become transparent when scrolled to the edge.
boolean • Default: falseWhen set to true, hides the tab bar.
unionThe color of every tab icon in the tab bar.
Acceptable values are: ColorValue | {
default: ColorValue | undefined,
selected: ColorValue | undefined
}
unionThe style of the every tab label in the tab bar.
Acceptable values are: StyleProp<NativeTabsLabelStyle> | {
default: StyleProp<NativeTabsLabelStyle>,
selected: StyleProp<NativeTabsLabelStyle>
}
stringThe visibility mode of the tab item label.
Acceptable values are: 'auto' | 'selected' | 'labeled' | 'unlabeled'
string • Default: automaticSpecifies the minimize behavior for the tab bar.
Available starting from iOS 26.
The following values are currently supported:
automatic- resolves to the system default minimize behaviornever- the tab bar does not minimizeonScrollDown- the tab bar minimizes when scrolling down and expands when scrolling back uponScrollUp- the tab bar minimizes when scrolling up and expands when scrolling back down
See: The supported values correspond to the official Apple documentation.
Acceptable values are: 'automatic' | 'never' | 'onScrollDown' | 'onScrollUp'
ColorValueThe color of the ripple effect when the tab is pressed.
unionListeners for navigation events on all tabs.
Supported events:
tabPress- called when a tab is pressedfocus- called when the screen comes into focusblur- called when the screen loses focus
Example
<NativeTabs screenListeners={{ tabPress: (e) => { console.log('Any tab pressed'); }, }} > ... </NativeTabs>
Acceptable values are: (prop: {
route: RouteProp<ParamListBase, string>
}) => ScreenListeners<TabNavigationState<ParamListBase>, NativeTabNavigationEventMap> | Partial<{
tabPress: EventListenerCallback<NativeTabNavigationEventMap & EventMapCore<TabNavigationState<ParamListBase>>, 'tabPress', false>
}>
booleanWhen set to true, enables the sidebarAdaptable tab bar style on iPadOS and macOS. This prop has no effect on iPhone.
ColorValueThe tint color of the tab icon.
Can be overridden by icon color and label color for each tab individually.
{
horizontal: number,
vertical: number
}See: Apple documentation
Type: React.Element<NativeTabTriggerProps>
The component used to customize the native tab options both in the _layout file and from the tab screen.
When used in the _layout file, you need to provide a name prop.
When used in the tab screen, the name prop takes no effect.
Example
import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function Layout() { return ( <NativeTabs> <NativeTabs.Trigger name="home" /> <NativeTabs.Trigger name="settings" /> </NativeTabs> ); }
Example
import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function HomeScreen() { return ( <View> <NativeTabs.Trigger> <NativeTabs.Trigger.Label>Home</NativeTabs.Trigger.Label> </NativeTabs.Trigger> <Text>This is home screen!</Text> </View> ); }
ReactNodeThe children of the trigger.
Use Icon, Label, and Badge components to customize the tab.
Pick<ViewStyle, 'backgroundColor' | 'experimental_backgroundImage' | 'alignContent' | 'alignItems' | 'flexDirection' | 'gap' | 'justifyContent' | 'padding' | 'paddingBottom' | 'paddingEnd' | 'paddingHorizontal' | 'paddingLeft' | 'paddingRight' | 'paddingStart' | 'paddingTop' | 'paddingVertical' | 'paddingBlock' | 'paddingBlockEnd' | 'paddingBlockStart' | 'paddingInline' | 'paddingInlineEnd' | 'paddingInlineStart'>The style applied to the content of the tab
Note: Only certain style properties are supported.
booleanThe default behavior differs between iOS and Android.
On Android, the content of a native tabs screen is automatically wrapped in a SafeAreaView,
and the bottom inset is applied. Other insets must be handled manually.
On iOS, the first scroll view nested inside a native tabs screen has automatic content inset adjustment enabled
When this property is set to true, automatic content inset adjustment is disabled for the screen
and must be managed manually. You can use SafeAreaView from react-native-screens/experimental
to handle safe area insets.
boolean • Default: falseIf true, the tab will not pop stack to the root when selected again.
boolean • Default: falseIf true, the tab will not scroll to the top when selected again.
booleanWhen set to true, the tab bar will not become transparent when scrolled to the edge.
When set on a trigger, it takes precedence over the value set on NativeTabs.
booleanIf true, the tab will be hidden from the tab bar.
Note: Marking a tab as
hiddenmeans it cannot be navigated to in any way.
Note: Dynamically hiding tabs will remount the navigator and the state will be reset.
unionListeners for navigation events on this tab.
Supported events:
tabPress- called when this tab is pressedfocus- called when this screen comes into focusblur- called when this screen loses focus
Example
<NativeTabs.Trigger name="home" listeners={{ tabPress: (e) => { console.log('Home tab pressed'); }, }} />
Acceptable values are: Partial<undefined> | (prop: {
route: RouteProp<ParamListBase, string>
}) => ScreenListeners<NavigationState, EventMapBase>
stringThe name of the route.
This is required when used inside a Layout component.
When used in a route it has no effect.
stringSystem-provided tab bar item with predefined icon and title
Uses Apple's built-in tab bar items (e.g., bookmarks, contacts, downloads) with
standard iOS styling and localized titles. Custom icon or selectedIcon
properties will override the system icon, but the system-defined title cannot
be customized.
See: The supported values correspond to the official Apple documentation.
Acceptable values are: 'search' | 'history' | 'bookmarks' | 'contacts' | 'downloads' | 'favorites' | 'featured' | 'more' | 'mostRecent' | 'mostViewed' | 'recents' | 'topRated'
Props passed to the underlying native tab screen implementation.
Use this to configure props not directly exposed by Expo Router, but available in react-native-screens.
Note: This will override any other props set by Expo Router and may lead to unexpected behavior.
Note: This is an unstable API and may change or be removed in minor versions.
Type: React.Element<FC<NativeTabsBottomAccessoryProps> & {
usePlacement: () => 'regular' | 'inline'
}>
ReactNodeType: React.Element<FC<NativeTabsTriggerBadgeProps>>
stringThe text to display as the badge for the tab. If not provided, the badge will not be displayed.
ColorValueType: React.Element<FC<NativeTabsTriggerIconProps>>
Type: React.Element<FC<NativeTabsTriggerLabelProps>>
StyleProp<NativeTabsLabelStyle>Type: React.Element<VectorIconProps<NameT>>
Helper component for loading vector icons.
Prefer using the md and sf props on Icon rather than using this component directly.
Only use this component when you need to load a specific icon from a vector icon family.
Example
import { Icon, VectorIcon } from 'expo-router'; import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'; <Icon src={<VectorIcon family={MaterialCommunityIcons} name="home" />} />
Interfaces
| Property | Type | Description |
|---|---|---|
| drawable(optional) | string | Only for: Android The name of the drawable resource to use as an icon. |
Material icon name for Android native tabs.
| Property | Type | Description |
|---|---|---|
| md | See description for available values. | Material icon glyph name. See the Material icons for the complete catalog. |
| Property | Type | Description |
|---|---|---|
| sf(optional) | SFSymbols7_0 | {
default: SFSymbols7_0 | undefined,
selected: SFSymbols7_0
} | Only for: iOS The name of the SF Symbol to use as an icon. The value can be provided in two ways:
Example
Example
|
| Property | Type | Description |
|---|---|---|
| renderingMode(optional) | 'template' | 'original' | Only for: iOS Controls how the image icon is rendered on iOS.
Default behavior:
|
| src(optional) | ReactElement<unknown, string | JSXElementConstructor<any>> | ImageSourcePropType | {
default: ReactElement<unknown, string | JSXElementConstructor<any>> | ImageSourcePropType | undefined,
selected: ReactElement<unknown, string | JSXElementConstructor<any>> | ImageSourcePropType
} | Only for: Android iOS The image source to use as an icon. When When The value can be provided in two ways:
Example
Example
|
| Property | Type | Description |
|---|---|---|
| xcasset(optional) | string | {
default: string,
selected: string
} | Only for: iOS The name of the iOS asset catalog image to use as an icon. Xcassets provide automatic multi-resolution (@1x/@2x/@3x), dark mode variants,
and device-specific images via The rendering mode (template vs original) can be controlled via the The value can be provided in two ways:
Example
Example
|
Types
Type: object shaped as below:
| Property | Type | Description |
|---|---|---|
| drawable(optional) | string | Only for: Android The name of the drawable resource to use as an icon. |
| sf(optional) | SFSymbol | Only for: iOS The name of the SF Symbol to use as an icon. |
| xcasset(optional) | string | Only for: iOS The name of the iOS asset catalog image to use as an icon. |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| renderingMode(optional) | 'template' | 'original' | Only for: iOS Controls how the icon is rendered on iOS. Default: 'template' |
| src(optional) | ImageSourcePropType | Promise<ImageSourcePropType | null> | The image source to use as an icon. |