Skip to main content
Version: 7.x

NavigationContainer

NavigationContainer 负责管理应用的导航状态并将顶层导航器链接到应用环境。

¥The NavigationContainer is responsible for managing your app's navigation state and linking your top-level navigator to the app environment.

该容器负责特定于平台的集成并提供各种有用的功能:

¥The container takes care of platform specific integration and provides various useful functionality:

  1. linking 属性的深度链接集成。

    ¥Deep link integration with the linking prop.

  2. 通知 屏幕跟踪状态持续性 等的状态更改。

    ¥Notify state changes for screen tracking, state persistence etc.

  3. 使用 React Native 的 BackHandler API 处理 Android 上的系统后退按钮。

    ¥Handle system back button on Android by using the BackHandler API from React Native.

用法:

¥Usage:

使用静态 API 时,createStaticNavigation 返回的组件相当于 NavigationContainer 组件。

¥When using the static API, the component returned by createStaticNavigation is equivalent to the NavigationContainer component.

import { createStaticNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator({
screens: {
/* ... */
},
});

const Navigation = createStaticNavigation(Stack);

export default function App() {
return <Navigation />;
}

参考号

¥Ref

可以将 ref 传递给容器以访问各种辅助方法,例如调度导航操作。这应该在你无法访问 navigation 对象 的极少数情况下使用,例如 Redux 中间件。

¥It's possible to pass a ref to the container to get access to various helper methods, for example, dispatch navigation actions. This should be used in rare cases when you don't have access to the navigation object, such as a Redux middleware.

示例:

¥Example:

import {
createStaticNavigation,
useNavigationContainerRef,
} from '@react-navigation/native';

export default function App() {
const navigationRef = useNavigationContainerRef(); // You can also use a regular ref with `React.useRef()`

return (
<View style={{ flex: 1 }}>
<Button onPress={() => navigationRef.navigate('Home')}>Go home</Button>
<Navigation ref={navigationRef} />
</View>
);
}
Try on Snack

如果你使用常规 ref 对象,请记住,在某些情况下(例如启用链接时),ref 最初可能是 null。为了确保引用已初始化,你可以使用 onReady 回调在导航容器完成安装时收到通知。

¥If you're using a regular ref object, keep in mind that the ref may be initially null in some situations (such as when linking is enabled). To make sure that the ref is initialized, you can use the onReady callback to get notified when the navigation container finishes mounting.

检查如何使用 TypeScript 此处 设置 ref

¥Check how to setup ref with TypeScript here.

有关详细信息,请参阅 无需导航属性即可导航 指南。

¥See the Navigating without the navigation prop guide for more details.

参考方法

¥Methods on the ref

ref 对象包括所有常见的导航方法,例如 navigategoBack 等。有关更多详细信息,请参阅 CommonActions 的文档

¥The ref object includes all of the common navigation methods such as navigate, goBack etc. See docs for CommonActions for more details.

示例:

¥Example:

navigationRef.navigate(name, params);

所有这些方法的行为就好像它们是在当前聚焦的屏幕内调用的一样。重要的是要注意,必须渲染一个导航器来处理这些操作。

¥All of these methods will act as if they were called inside the currently focused screen. It's important note that there must be a navigator rendered to handle these actions.

除了这些方法之外,ref 对象还包括以下特殊方法:

¥In addition to these methods, the ref object also includes the following special methods:

isReady

isReady 方法返回一个 boolean,指示导航树是否准备好。当 NavigationContainer 包含至少一个导航器并且所有导航器都已完成安装时,导航树已准备就绪。

¥The isReady method returns a boolean indicating whether the navigation tree is ready. The navigation tree is ready when the NavigationContainer contains at least one navigator and all of the navigators have finished mounting.

这可用于确定在不出现错误的情况下分派导航操作是否安全。详细信息请参见 处理初始化

¥This can be used to determine whether it's safe to dispatch navigation actions without getting an error. See handling initialization for more details.

resetRoot

resetRoot 方法允许你将导航树的状态重置为指定的状态对象:

¥The resetRoot method lets you reset the state of the navigation tree to the specified state object:

navigationRef.resetRoot({
index: 0,
routes: [{ name: 'Profile' }],
});

reset 方法不同,此方法作用于根导航器而不是当前聚焦屏幕的导航器。

¥Unlike the reset method, this acts on the root navigator instead of navigator of the currently focused screen.

getRootState

getRootState 方法返回一个 导航状态 对象,其中包含导航树中所有导航器的导航状态:

¥The getRootState method returns a navigation state object containing the navigation states for all navigators in the navigation tree:

const state = navigationRef.getRootState();

请注意,如果当前没有渲染导航器,则返回的 state 对象将为 undefined

¥Note that the returned state object will be undefined if there are no navigators currently rendered.

getCurrentRoute

getCurrentRoute 方法返回整个导航树中当前焦点屏幕的路由对象:

¥The getCurrentRoute method returns the route object for the currently focused screen in the whole navigation tree:

const route = navigationRef.getCurrentRoute();

请注意,如果当前没有渲染导航器,则返回的 route 对象将为 undefined

¥Note that the returned route object will be undefined if there are no navigators currently rendered.

getCurrentOptions

getCurrentOptions 方法返回整个导航树中当前聚焦屏幕的选项:

¥The getCurrentOptions method returns the options for the currently focused screen in the whole navigation tree:

const options = navigationRef.getCurrentOptions();

请注意,如果当前没有渲染导航器,则返回的 options 对象将为 undefined

¥Note that the returned options object will be undefined if there are no navigators currently rendered.

addListener

addListener 方法允许你监听以下事件:

¥The addListener method lets you listen to the following events:

state

每当导航树中任何导航器中的 导航状态 发生变化时,都会触发该事件:

¥The event is triggered whenever the navigation state changes in any navigator in the navigation tree:

const unsubscribe = navigationRef.addListener('state', (e) => {
// You can get the raw navigation state (partial state object of the root navigator)
console.log(e.data.state);

// Or get the full state object with `getRootState()`
console.log(navigationRef.getRootState());
});

这类似于 onStateChange 方法。唯一的区别是 e.data.state 对象可能包含部分状态对象,这与 onStateChange 中的 state 参数不同,后者始终包含完整状态对象。

¥This is analogous to the onStateChange method. The only difference is that the e.data.state object might contain partial state object unlike the state argument in onStateChange which will always contain the full state object.

options

每当导航树中当前聚焦屏幕的选项发生更改时,就会触发该事件:

¥The event is triggered whenever the options change for the currently focused screen in the navigation tree:

const unsubscribe = navigationRef.addListener('options', (e) => {
// You can get the new options for the currently focused screen
console.log(e.data.options);
});

属性

¥Props

initialState

接受导航器初始状态的属性。这对于深度链接、状态持久性等情况非常有用。

¥Prop that accepts initial state for the navigator. This can be useful for cases such as deep linking, state persistence etc.

示例:

¥Example:

<Navigation
initialState={initialState}
/>

有关状态对象结构的更多详细信息,请参阅 导航状态参考

¥See Navigation state reference for more details on the structure of the state object.

提供自定义初始状态对象将覆盖通过链接配置或从浏览器 URL 获取的初始状态对象。如果你要提供初始状态对象,请确保不要在网络上传递它,并且没有需要处理的深层链接。

¥Providing a custom initial state object will override the initial state object obtained via linking configuration or from browser's URL. If you're providing an initial state object, make sure that you don't pass it on web and that there's no deep link to handle.

示例:

¥Example:

const initialUrl = await Linking.getInitialURL();

if (Platform.OS !== 'web' && initialUrl == null) {
// Only restore state if there's no deep link and we're not on web
}

有关如何保留和恢复状态的更多详细信息,请参阅 状态持久化指南

¥See state persistence guide for more details on how to persist and restore state.

onStateChange

警告

将导航器的状态对象视为内部对象,并且可能会在次要版本中发生更改。避免使用除 indexroutes 之外的 导航状态 状态对象的属性,除非你确实需要它。如果某些功能在不依赖状态对象的结构的情况下无法实现,请提出问题。

¥Consider the navigator's state object to be internal and subject to change in a minor release. Avoid using properties from the navigation state state object except index and routes, unless you really need it. If there is some functionality you cannot achieve without relying on the structure of the state object, please open an issue.

每次 导航状态 更改时都会调用的函数。它接收新的导航状态作为参数。

¥Function that gets called every time navigation state changes. It receives the new navigation state as the argument.

你可以使用它来跟踪聚焦屏幕、保留导航状态等。

¥You can use it to track the focused screen, persist the navigation state etc.

示例:

¥Example:

<Navigation
onStateChange={(state) => console.log('New state is', state)}
/>

onReady

导航容器及其所有子容器首次完成安装后调用的函数。你可以将其用于:

¥Function which is called after the navigation container and all its children finish mounting for the first time. You can use it for:

示例:

¥Example:

<Navigation
onReady={() => console.log('Navigation container is ready')}
/>

如果容器内没有渲染导航器,则不会触发此回调。

¥This callback won't fire if there are no navigators rendered inside the container.

可以使用 ref 上的 isReady 方法获取当前状态。

¥The current status can be obtained with the isReady method on the ref.

onUnhandledAction

当任何导航器未处理导航操作时调用的函数。

¥Function which is called when a navigation action is not handled by any of the navigators.

默认情况下,当未处理操作时,React Navigation 将显示仅限开发的错误消息。你可以通过提供自定义函数来覆盖默认行为。

¥By default, React Navigation will show a development-only error message when an action is not handled. You can override the default behavior by providing a custom function.

示例:

¥Example:

<Navigation
onUnhandledAction={(action) => console.error('Unhandled action', action)}
/>

linking

用于深度链接的链接集成配置、浏览器中的 URL 支持等。

¥Configuration for linking integration used for deep linking, URL support in browsers etc.

示例:

¥Example:

import { createStaticNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const RootStack = createNativeStackNavigator({
screens: {
Home: {
screen: Home,
linking: {
path: 'feed/:sort',
},
},
},
});

const Navigation = createStaticNavigation(RootStack);

function App() {
const linking = {
prefixes: ['https://mychat.com', 'mychat://'],
};

return (
<Navigation
linking={linking}
fallback={<Text>Loading...</Text>}
/>
);
}

See 配置链接指南 for more details on how to configure deep links and URL integration.

¥See configuring links guide for more details on how to configure deep links and URL integration.

选项

¥Options

linking.prefixes

要处理的 URL 前缀。你可以提供多个前缀来支持自定义方案以及 通用链接

¥URL prefixes to handle. You can provide multiple prefixes to support custom schemes as well as universal links.

仅处理与这些前缀匹配的 URL。在解析之前,前缀将从 URL 中去除。

¥Only URLs matching these prefixes will be handled. The prefix will be stripped from the URL before parsing.

示例:

¥Example:

<Navigation
linking={{
prefixes: ['https://mychat.com', 'mychat://'],
}}
fallback={<Text>Loading...</Text>}
/>

仅 iOS 和 Android 支持此功能。

¥This is only supported on iOS and Android.

linking.config

配置来微调如何解析路径。

¥Config to fine-tune how to parse the path.

使用动态 API 时,配置对象应表示应用中导航器的结构。

¥When using dynamic API, the config object should represent the structure of the navigators in the app.

有关如何配置深层链接和 URL 集成的更多详细信息,请参阅 配置链接指南

¥See the configuring links guide for more details on how to configure deep links and URL integration.

linking.enabled

用于启用或禁用链接集成的可选布尔值。如果指定了 linking 属性,则默认为 true

¥Optional boolean to enable or disable the linking integration. Defaults to true if the linking prop is specified.

使用静态 API 时,可以传递 'auto' 以根据导航器的结构自动生成配置。有关更多详细信息,请参阅 配置链接指南

¥When using the static API, it's possible to pass 'auto' to automatically generate the config based on the navigator's structure. See the configuring links guide for more details.

linking.getInitialURL

默认情况下,链接与 React Native 的 Linking API 集成,并使用 Linking.getInitialURL() 为深度链接提供内置支持。但是,你可能还想处理来自其他来源的链接,例如 分支,或使用 Firebase 等推送通知。

¥By default, linking integrates with React Native's Linking API and uses Linking.getInitialURL() to provide built-in support for deep linking. However, you might also want to handle links from other sources, such as Branch, or push notifications using Firebase etc.

你可以提供自定义 getInitialURL 函数,你可以在其中返回我们应用作初始 URL 的链接。如果有要处理的 URL,则 getInitialURL 函数应返回 string,否则返回 undefined

¥You can provide a custom getInitialURL function where you can return the link which we should use as the initial URL. The getInitialURL function should return a string if there's a URL to handle, otherwise undefined.

例如,你可以执行以下操作来处理深度链接和 Firebase 通知

¥For example, you could do something like following to handle both deep linking and Firebase notifications:

import messaging from '@react-native-firebase/messaging';

<Navigation
linking={{
prefixes: ['https://mychat.com', 'mychat://'],
async getInitialURL() {
// Check if app was opened from a deep link
const url = await Linking.getInitialURL();

if (url != null) {
return url;
}

// Check if there is an initial firebase notification
const message = await messaging().getInitialNotification();

// Get the `url` property from the notification which corresponds to a screen
// This property needs to be set on the notification payload when sending it
return message?.data?.url;
},
}}
/>;

此选项在 Web 上不可用。

¥This option is not available on Web.

linking.subscribe

getInitialURL 类似,你可以提供自定义 subscribe 函数来处理任何传入链接,而不是默认的深层链接处理。subscribe 函数将接收一个监听器作为参数,只要有新的 URL 需要处理,你就可以使用 URL 字符串调用它。它应该返回一个清理函数,你可以在其中取消订阅你设置的任何事件监听器。

¥Similar to getInitialURL, you can provide a custom subscribe function to handle any incoming links instead of the default deep link handling. The subscribe function will receive a listener as the argument and you can call it with a URL string whenever there's a new URL to handle. It should return a cleanup function where you can unsubscribe from any event listeners that you have setup.

例如,你可以执行以下操作来处理深度链接和 Firebase 通知

¥For example, you could do something like following to handle both deep linking and Firebase notifications:

import messaging from '@react-native-firebase/messaging';

<Navigation
linking={{
prefixes: ['https://mychat.com', 'mychat://'],
subscribe(listener) {
const onReceiveURL = ({ url }: { url: string }) => listener(url);

// Listen to incoming links from deep linking
const subscription = Linking.addEventListener('url', onReceiveURL);

// Listen to firebase push notifications
const unsubscribeNotification = messaging().onNotificationOpenedApp(
(message) => {
const url = message.data?.url;

if (url) {
// Any custom logic to check whether the URL needs to be handled
//...

// Call the listener to let React Navigation handle the URL
listener(url);
}
}
);

return () => {
// Clean up the event listeners
subscription.remove();
unsubscribeNotification();
};
},
}}
/>

此选项在 Web 上不可用。

¥This option is not available on Web.

linking.getStateFromPath

你可以选择通过提供自己的实现来覆盖 React Navigation 解析状态对象链接的方式。

¥You can optionally override the way React Navigation parses links to a state object by providing your own implementation.

示例:

¥Example:

<Navigation
linking={{
prefixes: ['https://mychat.com', 'mychat://'],
getStateFromPath(path, config) {
// Return a state object here
// You can also reuse the default logic by importing `getStateFromPath` from `@react-navigation/native`
},
}}
/>
linking.getPathFromState

你可以选择通过提供自己的实现来覆盖 React Navigation 序列化状态对象以进行链接的方式。如果你指定了 getStateFromPath,这对于正确的 Web 支持是必要的。

¥You can optionally override the way React Navigation serializes state objects to link by providing your own implementation. This is necessary for proper web support if you have specified getStateFromPath.

示例:

¥Example:

<Navigation
linking={{
prefixes: ['https://mychat.com', 'mychat://'],
getPathFromState(state, config) {
// Return a path string here
// You can also reuse the default logic by importing `getPathFromState` from `@react-navigation/native`
},
}}
/>

fallback

当我们解析深层链接时,React Element 可以用作后备。默认为 null

¥React Element to use as a fallback while we resolve deep links. Defaults to null.

<Navigation
fallback={<Text>Loading...</Text>}
/>

如果你有原生启动画面,请使用 onReady 而不是 fallback 属性。

¥If you have a native splash screen, please use onReady instead of fallback prop.

documentTitle

默认情况下,React Navigation 会自动更新 Web 上的文档标题以匹配焦点屏幕的 title 选项。你可以使用此属性禁用它或自定义它。它接受具有以下选项的配置对象:

¥By default, React Navigation automatically updates the document title on Web to match the title option of the focused screen. You can disable it or customize it using this prop. It accepts a configuration object with the following options:

documentTitle.enabled

是否应启用文档标题处理。默认为 true

¥Whether document title handling should be enabled. Defaults to true.

documentTitle.formatter

如果你想自定义标题文本,请使用自定义格式化程序。默认为:

¥Custom formatter to use if you want to customize the title text. Defaults to:

(options, route) => options?.title ?? route?.name;

示例:

¥Example:

<Navigation
documentTitle={{
formatter: (options, route) =>
`${options?.title ?? route?.name} - My Cool App`,
}}
/>

theme

用于导航组件(如标题、选项卡栏等)的自定义主题。有关更多详细信息和使用指南,请参阅 主题指南

¥Custom theme to use for the navigation components such as the header, tab bar etc. See theming guide for more details and usage guide.

direction

应用中配置的文本方向。当 I18nManager.getConstants().isRTL 返回 true 时默认为 'rtl',否则为 'ltr'

¥The direction of the text configured in the app. Defaults to 'rtl' when I18nManager.getConstants().isRTL returns true, otherwise 'ltr'.

支持的值:

¥Supported values:

  • 'ltr':英语、法语等语言的从左到右文本方向。

    ¥'ltr': Left-to-right text direction for languages like English, French etc.

  • 'rtl':对于阿拉伯语、希伯来语等语言,文本方向从右到左。

    ¥'rtl': Right-to-left text direction for languages like Arabic, Hebrew etc.

示例:

¥Example:

<Navigation
direction="rtl"
/>

这用于各种导航器,以根据文本方向调整内容,例如,抽屉导航器 中的抽屉在 RTL 语言中位于右侧。

¥This is used in various navigators to adjust the content according to the text direction, for example, the drawer in the drawer navigator is positioned on the right side in RTL languages.

此 prop 告知 React Navigation 应用中的文本方向,它不会自行更改文本方向。如果你打算支持 RTL 语言,则必须将此属性设置为应用中配置的正确值。如果它与实际文本方向不匹配,则布局可能不正确。

¥This prop informs React Navigation about the text direction in the app, it doesn't change the text direction by itself. If you intend to support RTL languages, it's important to set this prop to the correct value that's configured in the app. If it doesn't match the actual text direction, the layout might be incorrect.

在 Web 上,可能还需要在应用的根元素上设置 dir 属性,以确保文本方向正确:

¥On the Web, it may also be necessary to set the dir attribute on the root element of the app to ensure that the text direction is correct:

<html dir="rtl">
<!-- App content -->
</html>

direction 将可通过 useLocale 钩子在你自己的组件中使用:

¥The direction will be available to use in your own components via the useLocale hook:

import { useLocale } from '@react-navigation/native';

function MyComponent() {
const { direction } = useLocale();

// Use the direction
}
警告

此 prop 的存在是为了向后兼容。不建议在新项目中使用它。它将在未来版本中被删除。

¥This prop exists for backward compatibility reasons. It's not recommended to use it in new projects. It will be removed in a future release.

在以前版本的 React Navigation 中,可以在嵌套导航器中导航到屏幕,而无需指定父屏幕的名称,即 navigation.navigate(ScreenName) 而不是 navigation.navigate(ParentScreenName, { screen: ScreenName })

¥In previous versions of React Navigation, it was possible to navigate to a screen in a nested navigator without specifying the name of the parent screen, i.e. navigation.navigate(ScreenName) instead of navigation.navigate(ParentScreenName, { screen: ScreenName }).

但是,它有几个问题:

¥However, it has a few issues:

  • 它仅在导航器已安装时才有效 - 使导航与其他逻辑耦合。

    ¥It only works if the navigator is already mounted - making navigation coupled to other logic.

  • 它不适用于 TypeScript 类型。

    ¥It doesn't work with the TypeScript types.

navigationInChildEnabled prop 允许你选择加入此行为,以便更轻松地迁移遗留代码。默认情况下禁用。

¥The navigationInChildEnabled prop allows you to opt-in to this behavior to make it easier to migrate legacy code. It's disabled by default.

有关新代码,请参阅 在嵌套导航器中导航到屏幕

¥For new code, see navigating to a screen in a nested navigator instead.

独立导航容器

¥Independent navigation containers

警告

这是一个高级用例。除非你 100% 确定需要它,否则不要使用它。

¥This is an advanced use case. Don't use this unless you are 100% sure that you need it.

在大多数应用中,只有一个 NavigationContainer。嵌套多个 NavigationContainer 将引发错误。但是,在极少数情况下,拥有多个独立的导航树可能会很有用,例如在较大的应用中包含一个迷你应用。

¥In most apps, there will be only a single NavigationContainer. Nesting multiple NavigationContainers will throw an error. However, in rare cases, it may be useful to have multiple independent navigation trees, e.g. including a mini-app inside a larger app.

你可以使用 NavigationIndependentTree 组件封装嵌套的 NavigationContainer,使其独立于父导航树:

¥You can wrap the nested NavigationContainer with the NavigationIndependentTree component to make it independent from the parent navigation tree:

import {
createStaticNavigation,
NavigationIndependentTree,
} from '@react-navigation/native';

/* content */

const Navigation = createStaticNavigation(RootStack);

function NestedApp() {
return (
<NavigationIndependentTree>
<Navigation />
</NavigationIndependentTree>
);
}

这样做会断开所有子导航器与父容器的连接,并且不允许在它们之间导航。

¥Doing this disconnects any children navigators from the parent container and doesn't allow navigation between them.

如果你需要与第三方组件(例如模式或底部表单)集成,请避免使用此选项。考虑使用 自定义导航器 代替。

¥Avoid using this if you need to integrate with third-party components such as modals or bottom sheets. Consider using a custom navigator instead.