Skip to main content
Version: 7.x

航海家

导航器负责管理和渲染一组屏幕。它可以使用 createXNavigator 函数创建,例如 createStackNavigatorcreateNativeStackNavigatorcreateBottomTabNavigatorcreateMaterialTopTabNavigatorcreateDrawerNavigator 等:

¥A navigator is responsible for managing and rendering a set of screens. It can be created using the createXNavigator functions, e.g. createStackNavigator, createNativeStackNavigator, createBottomTabNavigator, createMaterialTopTabNavigator, createDrawerNavigator etc.:

const MyStack = createNativeStackNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

除了内置导航器之外,还可以构建自定义导航器或使用第三方导航器。详细信息请参见 自定义导航器

¥In addition to the built-in navigators, it's also possible to build your custom navigators or use third-party navigators. See custom navigators for more details.

配置

¥Configuration

不同的导航器接受不同的配置选项。你可以在各自的文档中找到每个导航器的选项列表。

¥Different navigators accept different configuration options. You can find the list of options for each navigator in their respective documentation.

有一组通用配置在所有导航器之间共享:

¥There is a set of common configurations that are shared across all navigators:

ID

导航器的可选唯一 ID。这可以与 navigation.getParent 一起使用来在子导航器中引用该导航器。

¥Optional unique ID for the navigator. This can be used with navigation.getParent to refer to this navigator in a child navigator.

const MyStack = createNativeStackNavigator({
id: 'RootStack',
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

初始路由名称

¥Initial route name

导航器首次加载时渲染的路由名称。

¥The name of the route to render on the first load of the navigator.

const MyStack = createNativeStackNavigator({
initialRouteName: 'Home',
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

布局

¥Layout

布局是导航器的封装器。它可用于使用封装器为导航器增加额外的 UI。

¥A layout is a wrapper around the navigator. It can be useful for augmenting the navigators with additional UI with a wrapper.

与手动在导航器周围添加封装器的区别在于,布局回调中的代码可以访问导航器的状态、选项等。

¥The difference from adding a wrapper around the navigator manually is that the code in a layout callback has access to the navigator's state, options etc.

它需要一个返回 React 元素的函数:

¥It takes a function that returns a React element:

const MyStack = createNativeStackNavigator({
layout: ({ children, state, descriptors, navigation }) => (
<View style={styles.container}>
<Breadcrumbs
state={state}
descriptors={descriptors}
navigation={navigation}
/>
{children}
</View>
),
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

屏幕选项

¥Screen options

导航器中所有屏幕使用的默认选项。它接受一个对象或返回一个对象的函数:

¥Default options to use for all the screens in the navigator. It accepts either an object or a function returning an object:

const MyStack = createNativeStackNavigator({
screenOptions: {
headerShown: false,
},
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

有关更多详细信息和示例,请参阅 屏幕选项

¥See Options for screens for more details and examples.

屏幕监听器

¥Screen listeners

事件监听器可用于订阅为屏幕发出的各种事件。详细信息请参见 导航器上的 screenListeners 属性

¥Event listeners can be used to subscribe to various events emitted for the screen. See screenListeners prop on the navigator for more details.

屏幕布局

¥Screen layout

屏幕布局是导航器中每个屏幕的封装器。它使为导航器中的所有屏幕提供诸如错误边界和悬念回退之类的功能变得更容易,或者用额外的 UI 封装每个屏幕。

¥A screen layout is a wrapper around each screen in the navigator. It makes it easier to provide things such as an error boundary and suspense fallback for all screens in the navigator, or wrap each screen with additional UI.

它需要一个返回 React 元素的函数:

¥It takes a function that returns a React element:

const MyStack = createNativeStackNavigator({
screenLayout: ({ children }) => (
<ErrorBoundary>
<React.Suspense
fallback={
<View style={styles.fallback}>
<Text style={styles.text}>Loading…</Text>
</View>
}
>
{children}
</React.Suspense>
</ErrorBoundary>
),
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

路由

¥Router

警告

此 API 为实验性 API,可能会在小版本更新中发生更改。

¥This API is experimental and may change in a minor release.

可以使用导航器上的 UNSTABLE_router 属性自定义路由,以覆盖导航操作的处理方式。

¥Routers can be customized with the UNSTABLE_router prop on navigator to override how navigation actions are handled.

它接受一个函数,该函数接收原始路由并返回一个包含重写的对象:

¥It takes a function that receives the original router and returns an object with overrides:

const MyStack = createNativeStackNavigator({
UNSTABLE_router: (original) => ({
getStateForAction(state, action) {
if (action.type === 'SOME_ACTION') {
// Custom logic
}

// Fallback to original behavior
return original.getStateForAction(state, action);
},
}),
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});

传递给 UNSTABLE_router 的函数必须是纯函数,不能引用外部动态变量。

¥The function passed to UNSTABLE_router must be a pure function and cannot reference outside dynamic variables.

覆盖对象与原始路由进行浅合并。因此,你无需指定路由的所有属性,只需指定要覆盖的属性即可。

¥The overrides object is shallow merged with the original router. So you don't need to specify all properties of the router, only the ones you want to override.

有关路由的更多详细信息,请参阅 自定义路由

¥See custom routers for more details on routers.

路由名称更改行为

¥Route names change behavior

警告

此 API 为实验性 API,可能会在小版本更新中发生更改。

¥This API is experimental and may change in a minor release.

当导航器中的可用路由列表动态变化时(例如,基于条件渲染、循环遍历 API 数据等),导航器需要根据新的路由列表更新 导航状态

¥When the list of available routes in a navigator changes dynamically, e.g. based on conditional rendering, looping over data from an API etc., the navigator needs to update the navigation state according to the new list of routes.

默认情况下,其工作方式如下:

¥By default, it works as follows:

  • 任何不在新可用路由列表中的路由都将从导航状态中移除。

    ¥Any routes not present in the new available list of routes are removed from the navigation state

  • 如果当前聚焦的路由仍然存在于新的可用路由列表中,则该路由保持聚焦状态。

    ¥If the currently focused route is still present in the new available list of routes, it remains focused.

  • 如果当前焦点路由已被移除,但导航状态中存在其他在新可用列表中的路由,则渲染路由列表中的第一个路由将成为焦点。

    ¥If the currently focused route has been removed, but the navigation state has other routes that are present in the new available list, the first route in from the list of rendered routes becomes focused.

  • 如果导航状态中的任何路由都不在新可用路由列表中,则根据 UNSTABLE_routeNamesChangeBehavior 属性,可能会发生以下情况之一:

    ¥If none of the routes in the navigation state are present in the new available list of routes, one of the following things can happen based on the UNSTABLE_routeNamesChangeBehavior prop:

    • 'firstMatch' - 新路由列表中定义的第一个路由将获得焦点。这是基于路由中 getStateForRouteNamesChange 的默认行为。

      ¥'firstMatch' - The first route defined in the new list of routes becomes focused. This is the default behavior based on getStateForRouteNamesChange in the router.

    • 'lastUnhandled' - 恢复因条件渲染而未处理的最后一个状态。

      ¥'lastUnhandled' - The last state that was unhandled due to conditional rendering is restored.

状态可能未处理的示例:

¥Example cases where state might have been unhandled:

  • 打开了一个指向某个屏幕的深度链接,但却显示了登录屏幕。

    ¥Opened a deep link to a screen, but a login screen was shown.

  • 导航到包含导航器的屏幕,但显示的是另一个屏幕。

    ¥Navigated to a screen containing a navigator, but a different screen was shown.

  • 将导航器重置为包含与可用路由列表不匹配的不同路由的状态。

    ¥Reset the navigator to a state with different routes not matching the available list of routes.

在这种情况下,指定 'lastUnhandled' 将重用未处理的状态(如果存在)。如果没有未处理的状态,则会回退到 'firstMatch' 的行为。

¥In these cases, specifying 'lastUnhandled' will reuse the unhandled state if present. If there's no unhandled state, it will fallback to 'firstMatch' behavior.

注意事项:

¥Caveats:

  • 直接导航仅针对 NAVIGATE 操作。

    ¥Direct navigation is only handled for NAVIGATE actions.

  • 仅当当前状态失效时(即不包含任何已定义的屏幕),才会恢复未处理的状态。

    ¥Unhandled state is restored only if the current state becomes invalid, i.e. it doesn't contain any currently defined screens.

示例用法:

¥Example usage:

const RootStack = createNativeStackNavigator({
UNSTABLE_routeNamesChangeBehavior: 'lastUnhandled',
screens: {
Home: {
if: useIsSignedIn,
screen: HomeScreen,
},
SignIn: {
if: useIsSignedOut,
screen: SignInScreen,
options: {
title: 'Sign in',
},
},
},
});

最常见的用例是将其应用于 根据深度链接的身份验证显示正确的屏幕

¥The most common use case for this is to show the correct screen based on authentication based on deep link.