This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo 路由
一个适用于 React Native 和 web 应用的基于文件的路由库。
expo-router 是一个面向 React Native 和 web 应用的路由库。它通过基于文件的路由系统来实现导航管理,并提供原生导航组件。
了解 Expo Router 的基础知识、导航模式、核心概念等。
重要 在 SDK 56 及更高版本 中,Expo Router 不再支持在应用代码中从外部
@react-navigation/*包导入。请将这些导入重定向到相应的expo-router入口点。运行 codemod 或按照 SDK 55 到 56 迁移指南 更新你的项目。
安装
要在你的项目中使用 Expo Router,你需要先进行安装。请按照 Expo Router 安装指南中的说明操作:
了解如何在你的项目中安装 Expo Router。
在 app 配置中进行配置
如果你正在使用 默认 模板创建新项目,那么 expo-router 的 配置插件 已经在你的 app 配置中设置好了。
Example app.json with config plugin
Configurable properties
用法
关于核心概念、命名模式、导航布局以及常见导航模式,请从 Router 101 部分开始:
API
API
import { useRouter, Tabs, Navigator, Slot } from 'expo-router';
Components
Type: React.Element<BadgeProps>
Type: React.Element<ErrorBoundaryProps>
Type: React.Element<Omit<Omit<ExperimentalStackNavigatorProps, 'children' | 'initialRouteName' | 'layout' | 'screenListeners' | 'screenOptions' | 'screenLayout' | 'UNSTABLE_router' | 'UNSTABLE_routeNamesChangeBehavior' | 'id'> & DefaultRouterOptions<string> & { children: ReactNode; layout?: ((props: { state: StackNavigationState<ParamListBase>; navigation: NavigationHelpers<ParamListBase, {}>; descriptors: Record<...>; children: ReactNode; }) => ReactElement<...>) | undefined; ... 4 more ...; UNSTABLE_routeNamesChangeBehavior?: "firstMatch" | ... 1 more ... | undefined; ..., 'children'> & Partial<Pick<Omit<ExperimentalStackNavigatorProps, 'children' | 'initialRouteName' | 'layout' | 'screenListeners' | 'screenOptions' | 'screenLayout' | 'UNSTABLE_router' | 'UNSTABLE_routeNamesChangeBehavior' | 'id'> & DefaultRouterOptions<string> & { children: ReactNode; layout?: ((props: { state: StackNavigationState<ParamListBase>; navigation: NavigationHelpers<ParamListBase, {}>; descriptors: Record<...>; children: ReactNode; }) => ReactElement<...>) | undefined; ... 4 more ...; UNSTABLE_routeNamesChangeBehavior?: "firstMatch" | ... 1 more ... | undefined; ..., 'children'>>>
Renders the new react-native-screens/experimental native stack.
Sibling to Stack. Native-only — on web it falls back to the standard Stack.
Opt-in per navigator: replace <Stack /> with <ExperimentalStack /> in the
specific layout you want to migrate.
Type: React.Element<LabelProps>
Type: React.Element<React.FC>
Root style-reset for full-screen React Native web apps with a root <ScrollView /> should use the following styles to ensure native parity. Learn more.
Type: React.Element<React.FC>
Type: React.Element<Omit<NavigatorProps<any>, 'children'>>
Renders the currently selected content.
There are actually two different implementations of <Slot/>:
- Used inside a
_layoutas theNavigator - Used inside a
Navigatoras the content
Since a custom Navigator will set the NavigatorContext.contextKey to
the current _layout, you can use this to determine if you are inside
a custom navigator or not.
Type: React.Element<SuspenseFallbackProps>
Type: React.Element<Props>
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" />} />
{
getImageSource: (name: NameT, size: number, color: ColorValue) => Promise<ImageSourcePropType | null>
}The family of the vector icon.
Example
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
Type: React.Element<StackScreenProps>
Type: React.Element<ScreenProps<TabsProps, TabNavigationState<ParamListBase>, BottomTabNavigationEventMap>>
Type: React.Element<StackScreenBackButtonProps>
Component to configure the back button.
Can be used inside Stack.Screen in a layout or directly inside a screen component.
Example
import { Stack } from 'expo-router'; export default function Layout() { return ( <Stack> <Stack.Screen name="detail"> <Stack.Screen.BackButton displayMode="minimal">Back</Stack.Screen.BackButton> </Stack.Screen> </Stack> ); }
Example
import { Stack } from 'expo-router'; export default function Page() { return ( <> <Stack.Screen.BackButton hidden /> <ScreenContent /> </> ); }
Note: If multiple instances of this component are rendered for the same screen, the last one rendered in the component tree takes precedence.
Deprecated: Use
Stack.Titleinstead.
Type: React.Element<StackTitleProps>
Constants
Type: {
addListener: (eventType: EventType, callback: (event: Payload<EventType>) => void) => () => void,
emit: (type: EventType, event: Payload<EventType>) => void,
enable: () => void,
isEnabled: () => boolean
}
Hooks
Returns route info for a screen it is called from.
UrlObject | undefinedHook to run an effect whenever a route is focused. Similar to
React.useEffect, but the effect re-runs
each time the screen comes into focus, and the optional cleanup function runs when the
screen loses focus — not on unmount. This makes it the right primitive for refetching
data, restarting subscriptions, or resetting transient screen state every time a user
returns to the route.
The passed callback should be wrapped in React.useCallback
to avoid running the effect too often.
voidExample
import { useFocusEffect } from 'expo-router'; import { useCallback } from 'react'; export default function Route() { useFocusEffect( // Callback should be wrapped in `React.useCallback` to avoid running the effect too often. useCallback(() => { // Invoked whenever the route is focused. console.log("Hello, I'm focused!"); // Return function is invoked whenever the route gets out of focus. return () => { console.log('This route is now unfocused.'); }; }, []), ); return </>; }
Returns URL parameters for globally selected route, including dynamic path segments. This function updates even when the route is not focused. Useful for analytics or other background operations that don't draw to the screen.
Route URL example: acme://profile/baconbrix?extra=info.
When querying search params in a stack, opt-towards using
useLocalSearchParams because it will only update when the route is focused.
Note: For usage information, see Local versus global search parameters.
RouteOutputParams<TRoute> & TParamsExample
Hook to get the current focus state of the screen. Returns a true if screen is focused, otherwise false.
This can be used if a component needs to render something based on the focus state.
booleanReturns the result of the loader function for the calling route.
LoaderFunctionResult<T>Example
Returns the URL parameters for the contextually focused route. Useful for stacks where you may push a new screen that changes the query parameters. For dynamic routes, both the route parameters and the search parameters are returned.
Route URL example: acme://profile/baconbrix?extra=info.
To observe updates even when the invoking route is not focused, use useGlobalSearchParams.
Note: For usage information, see Local versus global search parameters.
RouteOutputParams<TRoute> & TParamsExample
Returns the navigation object for the current route. Mirrors the React Navigation
navigation object. Use it to
imperatively access layout-specific functionality like navigation.openDrawer() in a
Drawer layout.
TThe navigation object for the current route.
See: The full navigation API is available directly from
expo-router— no@react-navigation/*install required. For the navigator-dependent functions reference, see navigation dependent functions.
Example
When using nested layouts, you can access higher-order layouts by passing a secondary argument denoting the layout route.
For example, /menu/_layout.tsx is nested inside /app/orders/, you can use useNavigation('/orders/menu/').
Example
If you attempt to access a layout that doesn't exist, an error such as
Could not find parent navigation with route "/non-existent" is thrown.
NavigationContainerRefWithCurrent<RootParamList>The root <NavigationContainer /> ref for the app. The ref.current may be null
if the <NavigationContainer /> hasn't mounted yet.
Returns the currently selected route location without search parameters. For example, /acme?foo=bar returns /acme.
Segments will be normalized. For example, /[id]?id=normal becomes /normal.
stringExample
Deprecated: Use
useNavigationContainerRefinstead, which returns a Reactref.
NavigationContainerRef<RootParamList> | nullReturns the navigation state of the root navigator — the top-level navigator that contains the current screen.
NavigationStateThe current NavigationState of the root navigator.
See: React Navigation's navigation state reference for the shape of the returned object.
Example
import { useRootNavigationState } from 'expo-router'; export default function Route() { const { routes } = useRootNavigationState(); return <Text>{routes[0].name}</Text>; }
Hook to access the route prop of the parent screen anywhere.
TRoute prop of the parent screen.
Hook to get the path for the current route based on linking options.
string | undefinedPath for the current route.
Returns the Router object for imperative navigation.
ImperativeRouterExample
import { useRouter } from 'expo-router'; import { Text } from 'react-native'; export default function Route() { const router = useRouter(); return ( <Text onPress={() => router.push('/home')}>Go Home</Text> ); }
Returns a list of selected file segments for the currently selected route. Segments are not normalized,
so they will be the same as the file path. For example, /[id]?id=normal becomes ["[id]"].
RouteSegments<TSegments>Example
useSegments can be typed using an abstract. Consider the following file structure:
- app - [user] - index.tsx - followers.tsx - settings.tsx
This can be strictly typed using the following abstract with useSegments hook:
const [first, second] = useSegments<['settings'] | ['[user]'] | ['[user]', 'followers']>()
Returns the server document data for server-side rendering, including <html>/<body>
attributes and additional nodes to add to <head>/<body> for metadata and assets.
ServerDocumentDataExample
import { useServerDocumentContext } from 'expo-router/html'; export default function Root({ children }) { const { htmlAttributes, bodyAttributes, headNodes, bodyNodes } = useServerDocumentContext(); return ( <html {...htmlAttributes}> <head>{headNodes}</head> <body {...bodyAttributes}> {children} {bodyNodes} </body> </html> ); }
SitemapType | nullMethods
StackRouter is considered an internal implementation and its behavior may change without a notice between expo-router's version
Router<StackNavigationState<ParamListBase>, Action | StackActionType>TabRouter is considered an internal implementation and its behavior may change without a notice between expo-router's version
Router<TabNavigationState<ParamListBase>, Action | TabActionType>This API is unstable and may change between minor releases.
Creates a standard-navigation navigator and
wires it into Expo Router in one step. Use unstable_integrateWithRouter instead if you already
have a navigator from createStandardNavigator.
Component<PropsWithoutRef<PickPartial<StandardRouterNavigatorProps<State, NavigatorOptions, EventMap, NavigatorProps, RouterOptions>, 'children'>>> & {
Protected: FunctionComponent<ProtectedProps>,
Screen: (props: ScreenProps<NavigatorOptions, State, EventMap & EventMapBase>) => null
}Example
import { unstable_createStandardRouterNavigator, TabRouter } from 'expo-router'; export const Tabs = unstable_createStandardRouterNavigator(MyTabsContent, TabRouter);
This API is unstable and may change between minor releases.
Wires an existing standard-navigation
navigator into Expo Router, returning a navigator component (with a .Screen child) usable as a
layout. Use unstable_createStandardRouterNavigator to create and integrate in one step.
Component<PropsWithoutRef<PickPartial<StandardRouterNavigatorProps<State, NavigatorOptions, EventMap, NavigatorProps, RouterOptions>, 'children'>>> & {
Protected: FunctionComponent<ProtectedProps>,
Screen: (props: ScreenProps<NavigatorOptions, State, EventMap & EventMapBase>) => null
}Example
import { createStandardNavigator } from 'standard-navigation'; import { unstable_integrateWithRouter, TabRouter } from 'expo-router'; const navigator = createStandardNavigator(MyTabsContent); export const Tabs = unstable_integrateWithRouter(navigator, TabRouter);
Returns a navigator that automatically injects matched routes and renders nothing when there are no children.
Return type with children prop optional.
Enables use of other built-in React Navigation navigators and other navigators built with the React Navigation custom navigator API.
Component<PropsWithoutRef<PickPartial<ComponentProps<T>, 'children'>>> & {
Protected: FunctionComponent<ProtectedProps>,
Screen: (props: ScreenProps<TOptions, TState, TEventMap>) => null
}Example
Interfaces
Extends: BasePageEvent
The page rendered as part of a preload (e.g. router.prefetch()) and is not
currently focused. If the user later navigates to this route, the matching
pageFocused will fire then; the preload may also be invalidated or the
route unmounted (pageRemoved) without a focus.
Types
Literal type: union
Acceptable values are: PagePreloadedEvent | PageFocusedEvent | PageBlurredEvent | PageRemoved | ActionDispatchedEvent
Memoized callback containing the effect, should optionally return a cleanup function.
undefined | void | () => void
Navigator-level events emitted by ExperimentalStack. Mirrors the subset of
NativeStackNavigationEventMap that the gamma Stack.Screen lifecycle
callbacks can drive.
Options accepted by ExperimentalStack screens. Mirrors the narrow option
surface of the gamma <Stack.HeaderConfig> component from
react-native-screens/experimental. Anything outside this shape is dropped
with a __DEV__ warning at runtime.
Literal type: union
Acceptable values are: NavigationProp<ParamList, RouteName, NavigatorID, StackNavigationState<ParamList>, ExperimentalStackNavigationOptions, ExperimentalStackNavigationEventMap> | StackActionHelpers<ParamList>
Literal type: union
Acceptable values are: {string}:{string} | //{string}
The main routing type for Expo Router. It includes all available routes with strongly typed parameters. It can either be:
- string: A full path like
/profile/settingsor a relative path like../settings. - object: An object with a
pathnameand optionalparams. Thepathnamecan be a full path like/profile/settingsor a relative path like../settings. The params can be an object of key-value pairs.
An Href can either be a string or an object.
Generic: T
Type: T ? T[href] : string | HrefObject
Returns router object for imperative navigation API.
Example
import { router } from 'expo-router'; import { Text } from 'react-native'; export default function Route() { return ( <Text onPress={() => router.push('/home')}>Go Home</Text> ); }
Created by using a special file called +native-intent.tsx at the top-level of your
project's app directory. It exports redirectSystemPath or legacy_subscribe functions,
both methods designed to handle URL/path processing.
Useful for re-writing URLs to correctly target a route when unique/referred URLs are incoming from third-party providers or stale URLs from previous versions.
See: For more information on how to use
NativeIntent, see Customizing links.
Literal type: union
An item that can be displayed in the header. It can be a button, a menu, spacing, or a custom element.
On iOS 26, when showing items on the right side of the header,
if the items don't fit the available space, they will be collapsed into a menu automatically.
Items with type: 'custom' will not be included in this automatic collapsing behavior.
Acceptable values are: NativeStackHeaderItemButton | NativeStackHeaderItemMenu | NativeStackHeaderItemSpacing | NativeStackHeaderItemCustom
A button item in the header.
Type: SharedHeaderItem extended by:
A custom item to display any React Element in the header.
An item that shows a menu when pressed.
Type: SharedHeaderItem extended by:
An item to add spacing between other items in the header.
Literal type: union
Acceptable values are: NavigationProp<ParamList, RouteName, NavigatorID, StackNavigationState<ParamList>, NativeStackNavigationOptions, NativeStackNavigationEventMap> | StackActionHelpers<ParamList>
Type: NativeStackScreenProps<ParamList, RouteName, NavigatorID> extended by:
Literal type: union
The list of input keys will become optional, everything else will remain the same.
Literal type: union
Acceptable values are: ./{string} | ../{string} | '..'
Type: Exclude<Extract[pathname], RelativePathString | ExternalPathString>
Type: boolean or object shaped as below:
(name, params) => string | undefined
string | undefinedType: Record<string, {
canPreventDefault: boolean,
data: object | undefined
}>
Type: DefaultNavigatorOptions<ParamListBase, string | undefined, State, NavigatorOptions, EventMap & StandardNavigatorEventMapBase, any>