Skip to main content
Version: 6.x

从 5.x 升级

React Navigation 6 保留了与 React Navigation 5 相同的 API,但是进行了一些重大更改,以使 API 更加一致、更加灵活且更少混乱。

¥React Navigation 6 keeps the same API as React Navigation 5, however there are some breaking changes to make the API more consistent, more flexible and less confusing.

本指南列出了升级时需要记住的所有更改和新功能。

¥This guide lists all the changes and new features that you need to keep in mind when upgrading.

最低要求

¥Minimum Requirements

React Navigation 6 需要以下库的更新版本:

¥React Navigation 6 requires newer versions of following libraries:

  • react-native-safe-area-context >= 3.0.0

  • react-native-screens >= 2.15.0

  • react-native-tab-view >= 3.0.0

  • react-native >= 0.63.0

  • expo >= 41(如果你使用 Expo

    ¥expo >= 41 (if you use Expo)

  • typescript >= 4.1.0(如果你使用 TypeScript

    ¥typescript >= 4.1.0 (if you use TypeScript)

要将 react-native-safe-area-contextreact-native-screens 升级到最新支持的版本,请执行以下操作:

¥To upgrade react-native-safe-area-context and react-native-screens to the latest supported versions, do the following:

警告

如果你的 react-native 版本是 0.63.4 或更低,请不要在版本 4 中使用 react-native-safe-area-context,而只能在 3.4.1 之前使用。更多信息请参见此处

¥If your react-native Version is 0.63.4 or lower, don't use react-native-safe-area-context in Version 4, but only till 3.4.1. More Information see here

对于 Expo 管理的项目:

¥For Expo managed projects:

npx expo install react-native-safe-area-context react-native-screens

对于裸 React Native 项目:

¥For bare React Native projects:

npm install react-native-safe-area-context react-native-screens

请注意,现在默认启用最新版本的 react-native-screens。因此,如果由于某种原因无法启用它,则需要手动禁用它。

¥Note that latest versions of react-native-screens are now enabled by default. So you will need to disable it manually if you can't have it enabled for some reason.

重大变更和弃用表

¥Table of breaking changes and deprecations

升级指南包括新功能以及所有软件包的重大更改。下表是为了方便你快速查找所有重大更改和弃用的列表。

¥The upgrade guide includes both new features as well as breaking changes across all packages. The table below is for your convenience to quickly find the list of all the breaking changes and deprecations.

重大变化

¥Breaking changes

如果你使用相关 API,以下重大更改可能会破坏你的应用。所以升级时你可能需要更改代码。

¥The following breaking changes may break your app if you're using the related APIs. So you may need to change your code when upgrading.

弃用

¥Deprecations

如果你使用相关 API,以下更改将显示弃用警告,但你的代码将继续工作,并且可能会在以后更新。

¥The following changes will show deprecation warnings if you're using the related APIs, but your code will continue to work and may be updated at a later date.

关于混合 React Navigation 5 和 React Navigation 6 包的注意事项

¥Note on mixing React Navigation 5 and React Navigation 6 packages

为了使升级更容易,可以混合 6.x.x5.x.x 版本范围的软件包。但是,你需要记住以下几点:

¥To make upgrading easier, it is possible to mix packages from the 6.x.x and 5.x.x version ranges. However, there are a few things you need to keep in mind:

  • 如果你使用的是 @react-navigation/native@5.x.x6.x.x 版本的导航器:

    ¥If you're using @react-navigation/native@5.x.x and navigators with 6.x.x version:

    • 你需要安装最新的 5.x.x 版本的 @react-navigation/native 软件包,其中包括一些向后移植的 API。

      ¥You need to have latest 5.x.x version of @react-navigation/native package installed which includes some backported APIs.

    • 你无需担心 "一般变化" 部分下的任何重大更改。它们仅在你升级 @react-navigation/native 软件包时适用。

      ¥You don't need to worry about any of the breaking changes under "General changes" section. They are only applicable when you upgrade @react-navigation/native package.

  • 如果你使用的是 @react-navigation/native@6.x.x 和任何具有 5.x.x 版本的导航器:

    ¥If you're using @react-navigation/native@6.x.x and any navigators with 5.x.x version:

    • 请务必注意 "一般变化" 部分下的重大更改。其他一切都应该按预期工作。

      ¥Make sure to pay attention to the breaking changes under "General changes" section. Everything else should work as expected.

在这两种情况下,如果你使用 TypeScript,则在混合使用 5.x.x6.x.x 时可能会由于类型的变化而遇到类型错误。我们建议你忽略这些错误,直到你可以升级软件包。

¥In both cases, if you use TypeScript, you may encounter type errors when using mixing 5.x.x and 6.x.x due to changes in types. We suggest ignoring those errors until you can upgrade your packages.

一般变化

¥General changes

以下更改位于核心库中。升级 @react-navigation/native 软件包时,你需要解决此更改。

¥These following changes are in the core library. You'll need to address this changes when upgrading the @react-navigation/native package.

要安装 @react-navigation/native 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/native, run:

npm install @react-navigation/native

现在在导航上覆盖参数而不是合并

¥Params are now overwritten on navigation instead of merging

这可能是最大的变化之一。当导航到现有屏幕时,自 React Navigation 的第一个版本以来,我们已将新参数与现有参数合并。

¥This is probably one of the biggest changes. When navigating to an existing screen, we've merged the new params with the existing params since the first version of React Navigation.

例如,假设现有 Post 屏幕具有以下参数:

¥For example, let's say there's an existing Post screen with the following params:

{
postTitle: 'An amazing post',
postBody: 'Amazing content for amazing post'
}

然后你使用 navigation.navigate('Post', { postTitle: 'An okay post' }) 导航到它,它将具有以下参数:

¥And you navigate to it with navigation.navigate('Post', { postTitle: 'An okay post' }), it'll have the following params:

{
postTitle: 'An okay post',
postBody: 'Amazing content for amazing post'
}

虽然这种合并行为在某些情况下可能有用,但在其他情况下可能会出现问题。我们还收到了许多错误报告,其中用户对这种行为感到困惑。

¥While this merging behavior might be useful in some scenarios, it can be problematic in other cases. We also have had many bug reports where users were confused with this behavior.

因此,我们正在更改 React Navigation 6 中的默认行为,以便默认情况下不再合并参数,并且新参数将覆盖所有现有参数。

¥So we're changing the default behavior in React Navigation 6 so that the params aren't merged by default anymore, and new params overwrite all existing params.

虽然默认值已更改,但如果需要,仍然可以合并参数。要获得之前的行为,你可以将对象传递给 navigatemerge: true,它将合并参数:

¥While the default has changed, it's still possible to merge params if you need it. To get the previous behavior, you can pass an object to navigate with merge: true and it'll merge the params:

navigation.navigate({
name: 'Post',
params: { postTitle: 'An okay post' },
merge: true,
});

应该使用 merge: true 的常见情况是,如果你有自定义选项卡栏,因为当你通过点击选项卡栏更改选项卡时,预计参数不会被覆盖。

¥A common scenario where you should use merge: true is if you have a custom tab bar, since it's not expected that params will be overwritten when you change the tab by tapping on the tab bar.

dangerouslyGetParentdangerouslyGetState 中删除了 dangerously

¥Dropped dangerously from dangerouslyGetParent and dangerouslyGetState

navigation 属性上的 dangerouslyGetParentdangerouslyGetState 方法在许多场景中都很有用,有时甚至是必要的。因此,我们删除了 dangerously 前缀,以表明它可以安全使用。现在你可以使用 navigation.getParentnavigation.getState()

¥The dangerouslyGetParent and dangerouslyGetState methods on the navigation prop are useful in many scenarios, and sometimes necessary. So we dropped the dangerously prefix to make it clear that it's safe to use. Now you can use navigation.getParent and navigation.getState().

route 属性上不再有 state 属性

¥No more state property on the route prop

传递给组件的 route 属性通常包含保存子导航器状态的 state 属性。虽然它并不意味着公开,并且我们建议不要在文档中使用它,但我们已经看到很多人使用这个属性。

¥The route prop passed to components often contained a state property which held state of the child navigator. While it wasn't meant to be public and we recommended against using it in the docs, we've seen a lot of people use this property.

使用该属性是有问题的,因为在子导航器中进行导航之前不能保证它存在。这可能会在你的应用中导致你在开发过程中可能不会注意到的细微错误。因此,我们开始警告在 React Navigation 5 中使用此属性,并在 React Navigation 6 中完全删除此属性以防止其使用。

¥It's problematic to use the property since it's not guaranteed to exist before navigation happens in the child navigator. This can cause subtle bugs in your app which you might not notice during development. So we have started warning on using this property in React Navigation 5 and removed this property entirely in React Navigation 6 prevent its usage.

如果你需要根据子导航器中聚焦的屏幕进行一些配置,你仍然可以使用 getFocusedRouteNameFromRoute 实用程序来完成。

¥If you need to have some configuration based on which screen is focused in child navigator, you can still do it using the getFocusedRouteNameFromRoute utility.

route 属性上的新 path 属性

¥New path property on the route prop

从深层链接打开时,route 属性现在将包含 path 属性。你可以使用此属性进一步自定义屏幕内容,例如在 WebView 中加载页面。详细信息请参见 处理不匹配的路由或 404

¥The route prop will now contain a path property when opened from a deep link. You can use this property to further customize the content of the screen, e.g. load the page in a WebView. See Handling unmatched routes or 404 for more details.

链接配置现在更加严格

¥Linking configuration is now stricter

旧版本的 React Navigation 5 的链接配置格式略有不同。旧配置允许对象中存在键值对,而不管导航器的嵌套如何:

¥Older versions of React Navigation 5 had a slightly different configuration format for linking. The old config allowed a key value pair in the object regardless of nesting of navigators:

const config = {
Home: 'home',
Feed: 'feed',
Profile: 'profile',
Settings: 'settings',
};

假设你的 FeedProfile 屏幕嵌套在 Home 内。即使你没有使用上面的配置进行这样的嵌套,只要 URL 是 /home/profile,它就可以工作。此外,它还会将路径段和路由名称视为相同,这意味着你可以深层链接到配置中未指定的屏幕。例如,如果 Home 中有一个 Albums 屏幕,则深层链接 /home/Albums 将导航到该屏幕。虽然这在某些情况下可能是可取的,但无法阻止访问特定屏幕。这种方法还使得不可能出现 404 屏幕之类的情况,因为任何路由名称都是有效路径。

¥Let's say, your Feed and Profile screens are nested inside Home. Even if you don't have such a nesting with the above configuration, as long as the URL was /home/profile, it would work. Furthermore, it would also treat path segments and route names the same, which means that you could deep link to a screen that's not specified in the configuration. For example, if you have a Albums screen inside Home, the deep link /home/Albums would navigate to that screen. While that may be desirable in some cases, there's no way to prevent access to specific screens. This approach also makes it impossible to have something like a 404 screen since any route name is a valid path.

较新版本的 React Navigation 5 支持不同的配置格式,在这方面更加严格:

¥Newer versions of React Navigation 5 supported a different config format which is stricter in this regard:

  • 配置的形状必须与导航结构中嵌套的形状匹配

    ¥The shape of the config must match the shape of the nesting in the navigation structure

  • 只有配置中定义的屏幕才有资格进行深度链接

    ¥Only screens defined in the config will be eligible for deep linking

因此,你可以将上述配置重构为以下格式:

¥So, you'd refactor the above config to the following format:

const config = {
screens: {
Home: {
path: 'home',
screens: {
Feed: 'feed',
Profile: 'profile',
},
},
Settings: 'settings',
},
};

这里,配置对象有一个新的 screens 属性,FeedProfile 配置现在嵌套在 Home 下以匹配导航结构。

¥Here, there's a new screens property to the configuration object, and the Feed and Profile configs are now nested under Home to match the navigation structure.

虽然旧格式在 React Navigation 5 中仍然有效,但 React Navigation 6 完全放弃了对旧格式的支持,转而支持新的更严格的格式。

¥While the old format still worked in React Navigation 5, React Navigation 6 drops support for the old format entirely in favor of the new stricter format.

useLinking 钩子掉落

¥Dropped useLinking hook

useLinking hook 是 React Navigation 5 中深度链接的最初实现。后来,我们转向了 linking 属性,以便更轻松地处理深层链接。该钩子仍然被导出,以免破坏使用它的现有应用。

¥The useLinking hook was the initial implementation of deep linking in React Navigation 5. Later, we moved to the linking prop to make it easier to handle deep links. The hook was still exported not to break existing apps using it.

在 6.x 中,我们最终删除了该钩子,转而使用 linking 属性。如果你仍在使用 useLinking 钩子,那么迁移应该非常简单,因为你只需将配置传递给 linking 属性即可。

¥In 6.x, we finally removed the hook in favor of the linking prop. If you're still using the useLinking hook, it should be pretty straightforward to migrate as you just need to pass the config to linking prop instead.

有关配置深层链接的更多详细信息,请参阅 配置链接

¥See configuring links for more details on configuring deep links.

¥Link and useLinkProps can now accept screen names

此前,Link 组件只能接受路径字符串。现在你可以传递一个对象,该对象指定要导航到的屏幕名称以及要传递的任何参数:

¥Earlier, the Link component could only accept a path string. Now you can pass an object which specifies the screen name to navigate to, and any params to pass:

<Link
to={{
screen: 'Profile',
params: { id: 'jane' },
}}
>
Go to Jane's profile
</Link>

有关更多详细信息,请参阅 useLinkProps 文档。

¥See useLinkProps docs for more details.

Group 组件

¥New Group component

新的 Group 组件对于将相似的屏幕分组在一起非常有用。你可以使用它将一些常见选项传递到一堆屏幕。

¥The new Group component is useful for grouping similar screens together. You can use it to pass some common options to a bunch of screens.

例如,你可以将它用于一堆常规屏幕和一堆模态屏幕,而无需创建 2 个导航器:

¥For example, you can use it for a bunch of regular screen and a bunch of modal screens without having to create 2 navigators:

<Stack.Navigator>
<Stack.Group
screenOptions={{ headerStyle: { backgroundColor: 'papayawhip' }}}
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Group>
<Stack.Group screenOptions={{ presentation: 'modal' }}>
<Stack.Screen name="Search" component={SearchScreen} />
<Stack.Screen name="Share" component={ShareScreen} />
</Stack.Group>
</Stack.Navigator>

有关更多详细信息,请参阅 Group 文档。

¥See Group docs for more details.

用于导航器的新 screenListeners 属性与 screenOptions 类似

¥New screenListeners prop for navigators similar to screenOptions

现在可以使用 screenListeners 属性为导航器中的所有屏幕添加监听器。这对于监听所有屏幕的 tabPress、导航器级别的 state 变化等非常有用。

¥It's now possible to add listeners for all of the screens in a navigator by using the screenListeners prop. This can be useful to listen to things like tabPress for all screens, state change at the navigator level etc.

有关更多详细信息,请参阅 导航事件 的文档。

¥See docs for Navigation Events for more details.

用于创建容器引用的新钩子和助手

¥New hook and helper for creating container ref

新的 useNavigationContainerRef 钩子和 createNavigationContainerRef 辅助程序对于简化向 NavigationContainer 添加引用非常有用。

¥The new useNavigationContainerRef hook and createNavigationContainerRef helper are useful for simplifying adding a ref to to NavigationContainer.

有关更多详细信息和示例,请参阅 NavigationContainer无需导航属性即可导航 的文档。

¥See docs for NavigationContainer and Navigating without the navigation prop for more details and examples.

¥useNavigation, Link, useLinkProps etc. now work outside a screen

此前,useNavigationLinkuseLinkProps 等只能在屏幕内使用。但现在可以在 NavigationContainer 的子组件中使用它们。

¥Earlier, useNavigation, Link, useLinkProps etc. could only be used inside screens. But now it's possible to use them in any component that's a child of NavigationContainer.

对于选项卡和抽屉,backBehavior 的默认值现在是 firstRoute

¥The default value for backBehavior is now firstRoute for tabs and drawer

在应用中,按回键后返回第一条路由似乎更常见。为了匹配此行为,选项卡导航器(例如底部选项卡、材料顶部水龙头、材料底部选项卡等)以及抽屉导航器现在使用 firstRoute 作为 backBehavior 属性。为了保留旧的行为,你可以将 backBehavior="history" 属性传递给导航器。

¥Returning to first route after pressing back seems more common in apps. To match this behavior, the tab navigators such as bottom tabs, material top taps, material bottom tabs etc., as well as drawer navigator now use firstRoute for the backBehavior prop. To preserve old behavior, you can pass backBehavior="history" prop to the navigators.

如果你有自己的使用 TabRouterDrawerRouter 的自定义导航器,它也会受到此更改的影响,除非你指定了 backbehavior

¥If you have your own custom navigator using TabRouter or DrawerRouter, it will also be affected by this change unless you have specified a backbehavior.

TypeScript 的更严格类型

¥Stricter types for TypeScript

类型定义现在更加严格,这使得通过最小化不安全类型可以更容易地及早捕获错误。例如,如果你不指定类型,useNavigation 现在会显示类型错误。

¥The type definitions are now stricter, which makes it easier to catch errors earlier by minimizing unsafe types. For example, useNavigation now shows a type error if you don't specify a type.

你可以通过 注释它 来处理这个问题,或者更简单的方法是使用 指定根导航器的类型 来处理,它将用于 useNavigation 的所有使用。

¥You can handle this by annotating it, or for an easier way, specify a type for root navigator which will be used for all usage of useNavigation.

使用 TypeScript 时能够指定根导航器的类型

¥Ability to specify a type for root navigator when using TypeScript

以前,我们需要在每个使用 useNavigationLink 等的地方指定它们的类型。但现在可以在一处指定根导航器的类型,默认情况下将在任何地方使用:

¥Previously, we needed to specify a type for things such as useNavigation, Link etc. in every place we use them. But it's now possible to specify the type of the root navigator in one place that'll be used everywhere by default:

declare global {
namespace ReactNavigation {
interface RootParamList extends RootStackParamList {}
}
}

详细信息请参见 TypeScript 的文档

¥See the docs for TypeScript for more details.

TypeScript 的新 CompositeScreenProps 类型

¥New CompositeScreenProps type for TypeScript

我们现在有一个类似于 CompositeNavigationPropsCompositeScreenProps 辅助程序,可与 TypeScript 一起使用。详细信息请参见 组合导航属性

¥We now have a CompositeScreenProps helper similar to CompositeNavigationProps for usage with TypeScript. See Combining navigation props for more details.

堆栈导航器

¥Stack Navigator

@react-navigation/stack 包中进行了以下更改。

¥The following changes are in the @react-navigation/stack package.

要安装 @react-navigation/stack 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/stack, run:

npm install @react-navigation/stack

keyboardHandlingEnabled 移至选项

¥keyboardHandlingEnabled is moved to options

以前,keyboardHandlingEnabled 是导航器上的一个 prop,但现在需要在屏幕的 options 中指定。要保留以前的行为,你可以在 screenOptions 中指定它:

¥Previously, keyboardHandlingEnabled was a prop on the navigator, but now it needs to be specified in screen's options instead. To keep previous behavior, you can specify it in screenOptions:

<Stack.Navigator screenOptions={{ keyboardHandlingEnabled: false }}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>

mode="modal" 被删除,取而代之的是 presentation: 'modal'

¥mode="modal" is removed in favor of presentation: 'modal'

现在有一个新的 presentation 选项,允许你在每个屏幕的基础上自定义屏幕是否是模态的。

¥Now there is a new presentation option which allows you to customize whether a screen is a modal or not on a per screen basis.

此外,为了匹配 iOS 的默认行为,现在 presentation: 'modal' 展示了 iOS 13 中引入的新的呈现样式模式。它还会自动调整标题中的状态栏高度等内容,而你之前必须手动执行这些操作。此外,当屏幕动画时,状态栏内容的颜色会自动管理。

¥In addition, to match the default behavior of iOS, now presentation: 'modal' shows the new presentation style modal introduced in iOS 13. It also adjusts things like status bar height in the header automatically that you had to do manually before. In addition, the color of the statusbar content is automatically managed when the screen animates.

以前 Android 没有任何特殊的模态动画。但现在有一个从底部动画幻灯片而不是默认动画。

¥Previously Android didn't have any special animation for modals. But now there's a slide from bottom animation instead of the default animation.

如果你不想使用新动画,可以使用 动画相关选项.X 更改为你喜欢的动画。要使用 React Navigation 5 中的 iOS 模态动画,请使用 TransitionPresets.ModalSlideFromBottomIOS

¥If you don't want to use the new animations, you can change it to your liking using the animation related options. To use the iOS modal animation from React Navigation 5, use TransitionPresets.ModalSlideFromBottomIOS.

此外,新的 presentation: 'transparentModal' 选项可以更轻松地构建透明模态。有关更多详细信息,请参阅 透明模态 文档。

¥In addition, a new presentation: 'transparentModal' option to make it easier to build transparent modals. See transparent modals docs for more details.

更好地支持在单个堆栈中混合不同类型的动画

¥Better support for mixing different types of animations in a single stack

以前,有时需要为某些动画嵌套 2 个不同的堆栈导航器,例如:当我们想要使用模态呈现样式和常规样式时。

¥Previously, it was sometimes necessary to nest 2 different stack navigators for certain animations, for example: when we wanted to use modal presentation style and regular styles.

现在可以将常规屏幕与模式屏幕混合在同一堆栈中,因为这些选项不再需要应用于整个屏幕。

¥It is now possible to mix regular screens with modal screens in the same stack, since these options don't need to be applied to the whole screen anymore.

headerMode="none" 被删除,取而代之的是 headerShown: false

¥headerMode="none" is removed in favor of headerShown: false

以前,你可以传递 headerMode="none" 属性来隐藏堆栈导航器中的标头。但是,还有一个 headerShown 选项可用于隐藏或显示标题,并且它支持每个屏幕的配置。

¥Previously, you could pass headerMode="none" prop to hide the header in a stack navigator. However, there is also a headerShown option which can be used to hide or show the header, and it supports configuration per screen.

因此,我们没有使用 2 种方法来做非常相似的事情,而是删除了 headerMode="none",转而使用 headerShown: false。要获得旧行为,请在 screenOptions 中指定 headerShown: false

¥So instead of having 2 ways to do very similar things, we have removed headerMode="none" in favor of headerShown: false. To get the old behavior, specify headerShown: false in screenOptions:

<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>

headerMode 移至选项

¥headerMode is moved to options

以前,headerMode 是导航器上的一个 prop,但现在需要在屏幕的 options 中指定。要保留以前的行为,你可以在 screenOptions 中指定它:

¥Previously, headerMode was a prop on the navigator, but now it needs to be specified in screen's options instead. To keep previous behavior, you can specify it in screenOptions:

<Stack.Navigator screenOptions={{ headerMode: 'screen' }}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>

headerMode 选项支持 2 个值:screenfloat

¥The headerMode option supports 2 values: screen and float.

iOS 上模态中的标题现在更高

¥Header is now taller in modals on iOS

现在,标题在模态中的高度为 56dp,以匹配原生 iOS 样式。如果你使用 useHeaderHeight 钩子来获取标题的高度,则无需更改任何代码。

¥The header is now 56dp tall in modals to match the native iOS style. If you are using the useHeaderHeight hook to get the height of the header, then you won't need to change any code.

隐藏标题的标题高度现在被忽略

¥The header height from hidden header is now ignored

以前,如果标头隐藏在堆栈导航器中,useHeaderHeight 钩子将返回 0。现在它返回关闭可见标题的高度。

¥Previously, the useHeaderHeight hook returned 0 if the header was hidden in a Stack Navigator. Now it returns the height of the closes visible header instead.

自定义标头现在使用 'headerMode:默认屏幕

¥Custom header now uses 'headerMode: screen' by default

以前,使用自定义标头时需要手动指定 headerMode='screen' 或自定义动画。尽管文档中提到了这一点,但它已经被很多人绊倒了。

¥Previously it was necessary to specify headerMode='screen' or a custom animation manually when using a custom header. Even though this was mentioned in the docs, it has been tripped up many people.

但现在指定自定义标头会自动将 headerMode 设置为 screen,因此不再需要任何其他内容。现在这是可能的,因为 headerMode 不再是导航器的属性,因此可以在指定自定义标头的每个屏幕上进行配置。

¥But now specifying a custom header automatically sets headerMode to screen, so it doesn't need anything more. This is now possible because headerMode is no longer a prop for the navigator, so it can be configured per screen where a custom header is specified.

传递给自定义标头的属性得到简化

¥Props passed to custom header are streamlined

以前,堆栈头接受场景和前一个场景,其中包含 descriptornavigation prop、progress 等内容。这些 props 现在简化为以下内容。列表见 标题文档

¥Previously, the stack header accepted scene and previous scene which contained things such as descriptor, navigation prop, progress etc. The props are now simplified to following. See header docs for the list.

如果你有自定义标头,则可能需要调整它才能使用新的属性。

¥If you have a custom header, you may need to adjust it to use the new props.

标头现在使用 Flexbox

¥Header now uses flexbox

标题元素是使用绝对定位呈现的,这在某些情况下效果不佳。我们现在使用 Flexbox 作为标题元素,这应该可以更好地工作。

¥The header elements were rendered using absolute positioning which didn't work well in certain situations. We now use flexbox for header elements which should work better.

这可能不会为你带来任何改变,但如果你有依赖于绝对定位的代码,你可能需要更改它。

¥This probably doesn't change anything for you, but if you have code which relied on the absolute positioning, you may need to change it.

gestureResponseDistance 选项现在是数字而不是对象

¥The gestureResponseDistance option is now a number instead of an object

以前,gestureResponseDistance 选项采用具有 horizontalvertical 属性的对象。现在它需要一个数字,该数字将根据 gestureDirection 选项用作水平或垂直值。

¥Previously, the gestureResponseDistance option took an object with horizontal and vertical properties. Now it takes a number which will be used as the horizontal or vertical value based on the gestureDirection option.

现在支持 iPad 触控板上的两指返回手势

¥The two finger back gesture on trackpads in iPad is now supported

在 iPad 上,可以使用两根手指在原生应用中执行后退手势。现在在 Stack Navigator 中也可以实现这一点。

¥On iPad, it's possible to use two fingers to perform the back gesture in native apps. It's now also possible in Stack Navigator.

修复未启用 react-native-screens 时 Web 上的可访问性

¥Fix accessibility on Web when react-native-screens wasn't enabled

以前,即使禁用 react-native-screens,仍可在 Web 上访问未聚焦的屏幕。这已不再是这种情况。请注意,这仅在未启用动画时有效(这是 Web 上的默认设置)。否则,如果你禁用了 react-native-screens,则需要启用 react-native-screens 才能使其正常工作。

¥Previously, unfocused screens were still accessible on Web even if react-native-screens was disabled. This is no longer the case. Note that this only works when animations are not enabled (this is the default on Web). Otherwise, you'd need to enable react-native-screens to make it work if you had it disabled.

一些导出现在已移至元素库

¥Some exports are now moved to the element library

以下导出现在位于元素库中,因为它们不再特定于堆栈导航器:

¥The following exports now live in the elements library since they are no longer specific to the stack navigator:

  • Assets

  • HeaderTitle

  • HeaderBackButton

  • HeaderBackground

  • HeaderHeightContext

  • useHeaderHeight

有关安装元素库的更多详细信息,请参阅 below

¥See below for more details on installing the elements library.

原生堆栈导航器

¥Native Stack Navigator

@react-navigation/native-stack 包又回来了。我们对 API 进行了一些更改,以便在 @react-navigation/stack@react-navigation/native-stack 之间移动更加容易。如果你以前使用过 react-native-screens/native-stack,那么你需要对代码进行一些更改。

¥The @react-navigation/native-stack package is back. We made few changes to the API so that moving between @react-navigation/stack and @react-navigation/native-stack is easier. If you were using react-native-screens/native-stack before, then you'd need to make some changes to your code.

要安装 @react-navigation/native-stack 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/native-stack, run:

npm install @react-navigation/native-stack

react-native-screens/native-stack 的重大变更

¥Breaking changes from react-native-screens/native-stack

如果你从 react-native-screens/native-stack 导入 createNativeStackNavigator,则在迁移到 @react-navigation/native-stack 包时需要记住以下更改:

¥If you were importing createNativeStackNavigator from react-native-screens/native-stack, you need to keep the following changes in mind when migrating to @react-navigation/native-stack package:

Native 堆栈的选项

¥Options of Native Stack

  • backButtonInCustomView 选项已删除,现在会在必要时自动设置

    ¥backButtonInCustomView option is removed, it's now automatically set when necessary

  • headerCenter 选项已删除,headerLeftheaderRightheaderTitle 选项现在像 堆栈导航器 中一样工作

    ¥headerCenter option is removed, the headerLeft, headerRight and headerTitle options now work like they do in Stack Navigator

  • headerHideBackButton 更改为 headerBackVisible

    ¥headerHideBackButton is changed to headerBackVisible

  • headerHideShadow 更改为 headerShadowVisible

    ¥headerHideShadow is changed to headerShadowVisible

  • headerLargeTitleHideShadow 更改为 headerLargeTitleShadowVisible

    ¥headerLargeTitleHideShadow is changed to headerLargeTitleShadowVisible

  • headerTranslucent 更改为 headerTransparent

    ¥headerTranslucent is changed to headerTransparent

  • headerBlurEffect 现在是一个单独的选项,不再是 headerStyle 的属性

    ¥headerBlurEffect is now a separate option and no longer a property in headerStyle

  • headerTopInsetEnabled 选项已删除,现在会在必要时自动设置

    ¥headerTopInsetEnabled option is removed, it's now automatically set when necessary

  • disableBackButtonMenu 更改为 headerBackButtonMenuEnabled

    ¥disableBackButtonMenu is changed to headerBackButtonMenuEnabled

  • backButtonImage 更名为 headerBackImageSource

    ¥backButtonImage is renamed to headerBackImageSource

  • searchBar 更名为 headerSearchBarOptions

    ¥searchBar is renamed to headerSearchBarOptions

  • replaceAnimation 更名为 animationTypeForReplace

    ¥replaceAnimation is renamed to animationTypeForReplace

  • stackAnimation 更名为 animation

    ¥stackAnimation is renamed to animation

  • stackPresentation 更名为 presentation - 值 push 现在称为 card

    ¥stackPresentation is renamed to presentation - the value push is now called card

  • direction 选项被删除,现在根据 I18nManager.isRTL 自动设置

    ¥direction option is removed, it's now automatically set based on I18nManager.isRTL

活动

¥Events

appeardisappear 事件已被删除,取而代之的是 transitionStarttransitionEnd 事件,其中 e.data.closing 指示屏幕是打开还是关闭。

¥The appear and disappear events have been removed in favor of transitionStart and transitionEnd events with e.data.closing indicating whether the screen is being opened or closed.

Native Stack 现在可以在 Web 上运行

¥Native Stack now works on web

此前,native-stack 只能在 Android 和 iOS 上使用。但我们还添加了基本的 Web 支持,以便你可以编写跨平台应用,而无需更改代码。

¥Previously, native-stack could only be used on Android & iOS. But we also added basic web support so that you can write cross-platform apps without having to change your code.

底部选项卡导航器

¥Bottom Tab Navigator

@react-navigation/bottom-tabs 包中进行了以下更改。

¥The following changes are in the @react-navigation/bottom-tabs package.

要安装 @react-navigation/bottom-tabs 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/bottom-tabs, run:

npm install @react-navigation/bottom-tabs

默认情况下,选项卡屏幕中显示标题

¥A header is shown by default in tab screens

选项卡屏幕现在默认显示标题,类似于堆栈导航器中的屏幕。这避免了仅仅为了标题而在每个屏幕中嵌套堆栈导航器的需要。请参阅 它的选择 以查看所有标头相关选项。

¥Tab screens now show a header by default similar to screens in a stack navigator. This avoid the need for nesting a stack navigator in each screen just for a header. See its options to see all header related options.

要保持以前的行为,你可以在 screenOptions 中使用 headerShown: false

¥To keep the previous behavior, you can use headerShown: false in screenOptions.

当未传递图标时,选项卡栏现在显示问号而不是空白区域

¥The tab bar now shows a question mark when an icon isn't passed instead of empty area

以前,当未指定图标时,底部选项卡中的选项卡栏会显示空白区域。现在它显示一个问号,以更明显地表明该图标丢失了。

¥Previously the tab bar in bottom tabs showed an empty area when no icon was specified. Now it shows a question mark to make it more obvious that the icon is missing.

tabBarOptions 属性被移除,取而代之的是用于底部选项卡的更灵活的 options

¥The tabBarOptions prop is removed in favor of more flexible options for bottom tabs

tabBarOptions 属性被删除,其中的选项被移至屏幕的 options 上。这使得它们可以在每个屏幕的基础上进行配置。

¥The tabBarOptions prop was removed and the options from there were moved to screen's options instead. This makes them configurable on a per screen basis.

选项列表及其新名称如下:

¥The list of the options and their new name are follows:

  • keyboardHidesTabBar -> tabBarHideOnKeyboard

  • activeTintColor -> tabBarActiveTintColor

  • inactiveTintColor -> tabBarInactiveTintColor

  • activeBackgroundColor -> tabBarActiveBackgroundColor

  • inactiveBackgroundColor -> tabBarInactiveBackgroundColor

  • allowFontScaling -> tabBarAllowFontScaling

  • showLabel -> tabBarShowLabel

  • labelPosition -> tabBarLabelPosition

  • labelStyle -> tabBarLabelStyle

  • iconStyle -> tabBarIconStyle

  • tabStyle -> tabBarItemStyle

  • style -> tabBarStyle

adaptive 选项已被删除,因为你已经可以通过指定 tabBarLabelPosition 来禁用自动标签定位。

¥The adaptive option is removed since you can already disable the automatic label positioning by specifying a tabBarLabelPosition.

旧选项仍将继续使用,并带有弃用警告。为了避免弃用警告,请将它们移至 screenOptions

¥The old options will still keep working with a deprecation warning. To avoid the deprecation warning, move these to screenOptions.

tabBarVisible 选项不再存在

¥The tabBarVisible option is no longer present

由于选项卡栏现在支持 tabBarStyle 选项,因此我们删除了 tabBarVisible 选项。你可以通过在 options 中指定 tabBarStyle: { display: 'none' } 来实现相同的行为。

¥Since the tab bar now supports a tabBarStyle option, we have removed the tabBarVisible option. You can achieve the same behavior by specifying tabBarStyle: { display: 'none' } in options.

lazy 属性已移至 lazy 选项,用于底部选项卡的每屏幕配置

¥The lazy prop is moved to lazy option for per-screen configuration for bottom tabs

现在可以为每个屏幕而不是整个导航器配置 lazy 属性。所以它从 props 移到了 options。要保留以前的行为,你可以在 screenOptions 中指定它以将其应用到所有屏幕。

¥The lazy prop now can be configured per screen instead of for the whole navigator. So it's moved to options from props. To keep previous behavior, you can specify it in screenOptions to apply it to all screens.

用于指定自定义背景的新 tabBarBackground 选项

¥New tabBarBackground option to specify custom backgrounds

新的 tabBarBackground 选项可用于向选项卡栏添加自定义背景,例如图片、渐变、模糊视图等,而无需手动封装 TabBar

¥The new tabBarBackground option is useful to add custom backgrounds to the tab bar such as images, gradients, blur views etc. without having to wrap the TabBar manually.

有关更多详细信息,请参阅 tabBarBackground 的文档。

¥See docs for tabBarBackground for more details.

材质顶部选项卡导航器

¥Material Top Tab Navigator

@react-navigation/material-top-tabs 包中进行了以下更改。

¥The following changes are in the @react-navigation/material-top-tabs package.

要安装 @react-navigation/material-top-tabs 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/material-top-tabs, run:

npm install @react-navigation/material-top-tabs react-native-tab-view

要将 react-native-pager-view 升级到最新支持的版本,请执行以下操作:

¥To upgrade react-native-pager-view to the latest supported version, do the following:

对于 Expo 管理的项目:

¥For Expo managed projects:

npx expo install react-native-pager-view

对于裸 React Native 项目:

¥For bare React Native projects:

npm install react-native-pager-view

材质顶部选项卡现在使用 ViewPager 而不是 Reanimated 和 Gesture Handler

¥Material Top Tabs now uses ViewPager instead of Reanimated and Gesture Handler

react-native-tab-view 依赖已升级到最新版本 (3.x),现在使用 react-native-pager-view 而不是 Reanimated 和 Gesture Handler。这将提供原生用户体验并提高性能。

¥The react-native-tab-view dependency is upgraded to the latest version (3.x) which now uses react-native-pager-view instead of Reanimated and Gesture Handler. This will provide a native UX and also improve the performance.

详细信息请参见 react-native-tab-view 的发行说明

¥See release notes for react-native-tab-view for more details.

tabBarOptions 属性被移除,取而代之的是用于材料顶部标签的更灵活的 options

¥The tabBarOptions prop is removed in favor of more flexible options for material top tabs

与底部选项卡类似,tabBarOptions 属性被删除,其中的选项已移至屏幕的 options

¥Similar to bottom tabs, the tabBarOptions prop was removed and the options from there were moved to screen's options instead.

选项列表及其新名称如下:

¥The list of the options and their new name are follows:

  • activeTintColor -> tabBarActiveTintColor

  • inactiveTintColor -> tabBarInactiveTintColor

  • pressColor -> tabBarPressColor

  • pressOpacity -> tabBarPressOpacity

  • showLabel -> tabBarShowLabel

  • showIcon -> tabBarShowIcon

  • allowFontScaling -> tabBarAllowFontScaling

  • bounces -> tabBarBounces

  • scrollEnabled ->tabBarScrollEnabled

  • iconStyle -> tabBarIconStyle

  • labelStyle -> tabBarLabelStyle

  • tabStyle -> tabBarItemStyle

  • indicatorStyle -> tabBarIndicatorStyle

  • indicatorContainerStyle -> tabBarIndicatorContainerStyle

  • contentContainerStyle -> tabBarContentContainerStyle

  • style -> tabBarStyle

旧选项仍将继续使用,并带有弃用警告。为了避免弃用警告,请将它们移至 screenOptions

¥The old options will still keep working with a deprecation warning. To avoid the deprecation warning, move these to screenOptions.

lazy 属性已移至 lazy 选项,用于材质顶部选项卡的每屏幕配置

¥The lazy prop is moved to lazy option for per-screen configuration for material top tabs

与底部选项卡类似,材质顶部选项卡的 lazy 属性现在已移至 options

¥Similar to bottom tabs, the lazy prop is now moved to options for material top tabs.

lazyPlaceholder 属性已移至 lazyPlaceholder 选项,用于材质顶部选项卡的每屏幕配置

¥The lazyPlaceholder prop is moved to lazyPlaceholder option for per-screen configuration for material top tabs

材质顶部选项卡的 lazyPlaceholder 属性现已移至 options,以便你可以在每个屏幕的选项中配置占位符。

¥The lazyPlaceholder prop is now moved to options for material top tabs so you can configure a placeholder in each screen's options.

材质底部选项卡导航器

¥Material Bottom Tab Navigator

@react-navigation/material-bottom-tabs 包中进行了以下更改。

¥The following changes are in the @react-navigation/material-bottom-tabs package.

要安装 @react-navigation/material-bottom-tabs 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/material-bottom-tabs, run:

npm install @react-navigation/material-bottom-tabs

材质底部选项卡现在使用 react-native-safe-area-context 应用安全区域插图

¥Material Bottom Tabs now uses react-native-safe-area-context to apply safe area insets

现在使用 @react-navigation/material-bottom-tab 时需要安装 react-native-safe-area-context 软件包(如果你尚未安装)。

¥It's now necessary to install the react-native-safe-area-context package when using @react-navigation/material-bottom-tab, if you didn't have it already.

抽屉导航器

¥Drawer Navigator

@react-navigation/drawer 包中进行了以下更改。

¥The following changes are in the @react-navigation/drawer package.

要安装 @react-navigation/drawer 的 6.x 版本,请运行:

¥To install the 6.x version of @react-navigation/drawer, run:

npm install @react-navigation/drawer

Drawer 现在使用 Reanimated 2(如果有)

¥Drawer now uses Reanimated 2 if available

有一个基于最新 复活 的新实现,如果可用,将使用该实现,否则抽屉将回退到旧实现。

¥There is a new implementation based on the latest Reanimated which will be used if it's available, otherwise drawer will fallback to the old implementation.

如果需要,你可以将 useLegacyImplementation={true} 传递给 Drawer.Navigator 以强制它始终使用旧的实现。

¥You can pass useLegacyImplementation={true} to Drawer.Navigator to force it to always use the old implementation if you need.

默认情况下,抽屉式屏幕中会显示标题

¥A header is shown by default in drawer screens

选项卡屏幕现在默认显示标题,类似于堆栈导航器和底部选项卡导航器中的屏幕。请参阅 它的选择 以查看所有标头相关选项。

¥Tab screens now show a header by default similar to screens in a stack navigator and bottom tab navigator. See its options to see all header related options.

要保持以前的行为,你可以在 screenOptions 中使用 headerShown: false

¥To keep the previous behavior, you can use headerShown: false in screenOptions.

幻灯片动画现已成为 iOS 上的默认动画

¥Slide animation is now default on iOS

Drawer 现在在 iOS 上默认使用幻灯片动画。要保持以前的行为,你可以在 screenOptions 中指定 drawerType="front"

¥Drawer now uses a slide animation by default on iOS. To keep the previous behavior, you can specify drawerType="front" in screenOptions.

抽屉状态现在是字符串而不是布尔值

¥Drawer status is now a string instead of a boolean

以前,抽屉的状态是 boolean (true | false),表示打开和关闭状态。现在它是一个值为 openclosed 的字符串。这将使我们将来实现更多类型的状态。

¥Previously, the status of drawer was a boolean (true | false) to signify the open and closed states. It's now a string with the values open and closed. This will let us implement more types of status in future.

为了匹配此更改,以下 API 也已重命名:

¥To match this change, the following APIs have been renamed as well:

  • getIsDrawerOpenFromState -> getDrawerStatusFromState

  • useIsDrawerOpen -> useDrawerStatus

  • openByDefault -> defaultStatus

抽屉不再发出 drawerOpendrawerClose 事件

¥Drawer no longer emits drawerOpen and drawerClose events

drawerOpendrawerClose 事件现已删除,因为可以从以下辅助程序获得相同的信息:

¥The drawerOpen and drawerClose events are now removed because same information can be achieved from the following helpers:

  • useDrawerStatus

    ¥useDrawerStatus hook

  • getDrawerStatusFromState 助手(例如 - getDrawerStatusFromState(navigation.getState())

    ¥getDrawerStatusFromState helper (e.g. - getDrawerStatusFromState(navigation.getState()))

抽屉的 drawerContentOptions 属性现在更灵活,移动到 options

¥The drawerContentOptions prop is now more flexible by moving to options for drawer

drawerContentOptions 属性被删除,其中的选项被移至屏幕的 options 上。这使得它们可以在每个屏幕的基础上进行配置。

¥The drawerContentOptions prop was removed and the options from there were moved to screen's options instead. This makes them configurable on a per screen basis.

以下选项已移动但未重命名:

¥The following options have been moved without renaming:

  • drawerPosition

  • drawerType

  • keyboardDismissMode

  • overlayColor

  • gestureHandlerProps

以下选项已被移动并重命名:

¥The following options have been moved and renamed:

  • hideStatusBar -> drawerHideStatusBarOnOpen

  • statusBarAnimation -> drawerStatusBarAnimation

  • edgeWidth -> swipeEdgeWidth

  • minSwipeDistance -> swipeMinDistance

旧选项仍将继续使用,并带有弃用警告。为了避免弃用警告,请将它们移至 screenOptions

¥The old options will still keep working with a deprecation warning. To avoid the deprecation warning, move these to screenOptions.

drawerContent 属性不再在其参数中接收 progress

¥The drawerContent prop no longer receives progress in its argument

传递给 drawerContent 的回调不再在其参数中接收动画 progress 值。相反,你可以使用 useDrawerProgress 钩子来获取当前进度值。

¥The callback passed to drawerContent no longer receives the animated progress value in its argument. Instead, you can use the useDrawerProgress hook to get the current progress value.

function CustomDrawerContent(props) {
const progress = useDrawerProgress();

// ...
}

// ...

<Drawer.Navigator drawerContent={(props) => <CustomDrawerContent {...props} />}>

useDrawerProgress 钩子返回 Reanimated Node 或 Reanimated SharedValue,具体取决于所使用的实现。

¥The useDrawerProgress hook returns a Reanimated Node or Reanimated SharedValue depending on the implementation used.

lazy 属性已移至 lazy 选项,用于抽屉的每屏幕配置

¥The lazy prop is moved to lazy option for per-screen configuration for drawer

与底部选项卡类似,抽屉的 lazy 属性现在移至 options

¥Similar to bottom tabs, the lazy prop is now moved to options for drawer.

元素库

¥Elements Library

我们有一个新包,其中包含与导航相关的各种 UI 元素,例如 Header 组件。这意味着我们现在可以在所有导航器中使用这些组件。你还可以安装该库以导入 Header 等组件以在任何导航器中使用:

¥We have a new package which contains various UI elements related to navigation, such as a Header component. This means that we can now use these components in all navigators. You can also install the library to import components such as Header to use in any navigator:

npm install @react-navigation/elements

现在你可以从那里导入项目:

¥Now you can import items from there:

import { useHeaderHeight } from '@react-navigation/elements';

有关库中可用内容的更多详细信息,请参阅 元素库页面

¥See the Elements Library page for more details on what's available in the library.

开发者工具

¥Developer tools

React Navigation 有一个新的 Flipper 插件,可以帮助你调试导航和深层链接配置。

¥There's a new Flipper plugin for React Navigation to help you debug your navigation and deep link config.

有关如何安装和配置它的更多详细信息,请参阅 useFlipper 的文档。

¥See docs for useFlipper for more details on how to install and configure it.