React-Navigation 从5.x 升级到 6.x【译】

827 阅读15分钟

从 5.x 升级

React Navigation 6 保持了与 React Navigation 5 相同的 API,但是也有一些破坏性变更使 API 更加一致,灵活,且不容易混淆。

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

最低版本要求

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

  • 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
  • typescript >= 4.1.0 (如果你使用 TypeScript

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

提示:

如果你的 react-native 版本 <= 0.63.4,不要使用 v4 版本的react-native-safe-area-context,继续使用 3.4.1。了解更多

对于使用 Expo 管理的项目:

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

对于普通的 React Native 项目:

npm

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

Yarn

yarn add react-native-safe-area-context react-native-screens

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

中断变化和弃用表

升级指南包括新特性以及跨所有包的破坏性更改。下表是为了方便您快速查找所有破坏性更改和弃用的列表。

通用变更

如果你正在使用相关的 api,下面的破坏性更改可能会破坏你的应用程序。因此,升级时可能需要更改代码。

  • 通用变更:这些更改影响所有 React Navigation 用户。

    • 导航参数(Params)在导航时会被覆盖,而不是合并
    • dangerouslyGetParentdangerouslyGetState 中废弃 dangerously
    • 在 route prop 中 不在有 state 属性
    • Linking 配置现在更加严格
    • 废弃 useLinking 钩子
    • tabs 和 drawer 的 backBehavior 属性的默认值现在改为 firstRoute
    • 更严格的 TypeScript 类型
  • Stack Navigator:这些更改会影响 @react-navigation/stack 软件包的用户。

    • 自定义 header 现在默认使用 'headerMode: screen'
    • Header 现在使用 flexbox 进行布局
    • 传递到自定义 header 的 props 被简化
    • gestureResponseDistance 选项现在是一个 number 而不是一个 object
    • 一些导出现在被移动到 element 库中
  • Bottom Tab Navigator:这些更改会影响 @react-navigation/bottom-tabs 软件包的用户。

    • 默认情况下,在选项卡屏幕中显示 header
  • Material Top Tab Navigator:这些更改会影响 @react-navigation/material-top-tabs 软件包的用户。

    • Material Top Tabs 现在使用 ViewPager 而不是 Reanimated 和 Gesture Handler
  • Material Bottom Tab Navigator:这些更改会影响 @react-navigation/material-bottom-tabs 软件包的用户。

    • Material Bottom Tab 现在使用 react-native-safe-area-context 来确认安全区域
  • Drawer Navigator:这些更改会影响 @react-navigation/drawer 软件包的用户。

    • 默认情况下,在抽屉屏幕中显示 header
    • 幻灯片动画现在是 iOS 上的默认设置
    • 抽屉 status 现在是字符串而不是布尔值
    • 抽屉不再触发 drawerOpendrawerClose 事件

废弃

如果您正在使用相关的 api,那么以下更改将显示弃用警告,但您的代码将继续工作,并可能在稍后的日期进行更新。

  • Stack Navigator:这些更改会影响 @react-navigation/stack 软件包的用户。

    • headerMode="none" 被移除,取而代之的是 headerShown: false
    • headerMode 被移到 options 中
    • mode="modal" 被移除,取而代之的是 presentation: 'modal'
    • keyboardHandlingEnabled 被移动到 options 中
  • Bottom Tab Navigator:这些更改会影响 @react-navigation/bottom-tabs 软件包的用户。

    • tabBarOptions 属性被删除,以支持底部选项卡更灵活的 options
    • tabBarVisible 选项不再存在
    • 对于底部选项卡的每个屏幕配置,lazy prop 被移动到 lazy option
  • Material Top Tab Navigator:这些更改会影响 @react-navigation/material-top-tabs 软件包的用户。

    • tabBarOptions props 被删除,以支持更灵活的 Material Top Tabs options
    • 对于 material top tabs 的每个屏幕配置,lazy prop 被移动到 lazy option
    • 对于 material top tabs 的每个屏幕配置, lazyPlaceholder prop 被移动到 lazyPlaceholder option
  • Drawer Navigator:这些更改会影响 @react-navigation/drawer 软件包的用户。

    • drawerContentOptions prop 现在通过移动到抽屉 options 变得更加灵活
    • 对于抽屉的每个屏幕配置,将 lazy prop 移动到 lazy option

关于混合使用 React Navigation 5 和 React Navigation 6 包需要注意的地方

为了使升级更容易,可以混合使用 6.x.x5.x.x 范围内的包。然而,这里还是有几件事你需要记住。

  • 如果你使用 @react-navigation/native@5.x.x6.x.x 版本的 navigators:
    • 您需要安装最新的 5.x.x 版本的 @react navigation/native 包,其中包括一些向后移植的 API。
    • 您不必担心 “通用变更” 部分下的任何破坏变化。仅当您升级 @react-navigation/native 软件包时,它们才适用。
  • 如果您使用的是 @react-navigation/native@6.x.x 以及 5.x.x 版本的任何 navigators:
    • 一定要注意 “通用变更” 部分下的突破性更改。其他一切都应该正常工作。

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

通用变更

以下更改位于核心库中。升级@react navigation/native包时,您需要解决这些更改。

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

npm

npm install @react-navigation/native

Yarn

yarn add @react-navigation/native

导航参数(Params)在导航时会被覆盖,而不是合并

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

举个例子,假设现在有一个带下列参数的 Post 屏幕:

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

如果你使用navigation.navigate('Post', { postTitle: 'An okay post' })导航,就会产生下列参数:

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

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

所以我们正在改变 React Navigation 6 中的默认行为,这样参数就不会在默认情况下被合并,新的参数会覆盖所有现有的参数。

虽然默认值已经改变,但如果需要,仍然可以合并参数。为了获得以前的行为,你可以传递一个带merge: true的对象给 navigate 来进行导航,它将合并参数。

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

应该使用merge: true的常见情况是,如果您有一个自定义的选项卡栏,因为当您通过点击选项卡栏更改选项卡时,并不期望 params 会被覆盖。

dangerouslyGetParentdangerouslyGetState 中废弃 dangerously

navigation props 上的 dangerlygetparentdangerlygetstate 方法在许多场景中都很有用,有时是必要的。所以我们去掉了这个 dangerously 前缀,以表明它是安全的。现在可以使用 navigation.getParent()navigation.getState()

route prop 中不在有 state 属性

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

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

如果您需要基于子导航器中聚焦哪个屏幕进行一些配置,您仍然可以使用 getFocusedRouteNameFromRoute 来实现这一点。

route prop 中加入新属性 path

当从深度链接(deep link)打开时,route prop 现在将包含 path 。你可以使用这个属性来进一步定制屏幕的内容,例如在 WebView 中加载页面。有关详细信息,请参见处理不匹配路由或 404

Linking 配置现在更加严格

React Navigation 5 的较旧版本的链接具有不同的配置格式。旧配置允许在对象中的键值对,而不管嵌套的导航器是什么:

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

假设,你的 FeedProfile 屏幕嵌套在 Home 中。即使您没有上述配置的嵌套,只要 URL 是/home/profile,它就可以工作。此外,它还会将路径段和路由名视为相同的,这意味着您可以深度链接到配置中没有指定的屏幕。举个例子,如果你有一个嵌套在 Home 中的 Albums 屏幕,深度链接 /home/Albums 将导航到该屏幕。尽管在某些情况下可能是理想的,但无法防止访问特定的屏幕。这种方法还使得不可能拥有像 404 屏幕之类的东西,因为任何路由名称都是有效的路径。

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

  • 配置的格式必须匹配导航结构中嵌套的格式
  • 只有在配置中定义的屏幕才有资格进行深度链接

因此,您需要将上述配置重构为以下格式:

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

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

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

废弃 useLinking 钩子

useLinking钩子是 React Navigation 5 中深度链接的最初实现。后来,我们移动到 linking prop,以便更容易处理深层链接。钩子仍然被导出,不会破坏使用它的现有应用程序。

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

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

LinkuseLinkProps 不能接受屏幕名称

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

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

更多细节请参见 useLinkProps 文档。

新的 Group 组件

新的 Group 组件用于将类似的屏幕分组在一起。您可以使用它将一些常用选项传递给一堆屏幕。

例如,你可以将它用于一堆常规屏幕和一堆模式屏幕,而不必创建两个导航器:

<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 文档。

新增导航器类似 screenOptions 属性的新属性 screenListeners

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

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

新的帮助创建容器 ref 的钩子

新的 useNavigationContainerRef 钩子和 createNavigationContainerRef 方法对于简单的项 NavigationContainer 添加引用来说非常有用。

有关更多详细信息和示例,请参阅 NavigationContainer不使用导航 prop 进行导航 的文档。

useNavigation, Link, useLinkProps 等。现在在屏幕外工作

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

tabs 和 drawer 的 backBehavior 属性的默认值现在改为 firstRoute

在应用程序中,按下后返回第一条路线似乎更常见。为了匹配此行为,tab 导航器(如 bottom tabs, material top taps, material bottom tabs 等),还有 drawer 导航器现在将 firstRoute 用于 backBehavior prop。

要保留旧行为,可以将 backBehavior=“history” 属性传递给导航器。

如果您使用 TabRouter DrawerRouter 拥有自己的自定义导航器,则除非您指定了 backbehavior,否则它也会受到此更改的影响。

更严格的 TypeScript 类型

类型定义现在更严格了,这使得通过最小化不安全类型来更早地捕获错误变得更容易。举个例子,如果不指定类型,useNavigation 现在会显示类型错误。

您可以通过对其进行注释来处理此问题,或者为根导航器指定一种类型,该类型将用于 useNavigation 的所有使用。

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

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

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

有关详细信息,请参阅TypeScript 的文档

新的 TypeScript 类型 CompositeScreenProps

我们现在有一个 CompositeScreenProps 助手,类似于 CompositeNavigationProps ,用于 TypeScript。有关详细信息,请参见组合导航 props

Stack Navigator

下列变更都在 @react-navigation/stack 包中。

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

npm

npm install @react-navigation/stack

Yarn

yarn add @react-navigation/stack

keyboardHandlingEnabled 被移动到 options 中

以前,keyboardHandlingEnabled 是导航器的一个 prop,但现在需要在屏幕 options 中指定。

要保持以前的行为,可以在 screenOptions 中指定它:

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

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

现在有了一个新的 presentation 选项,它允许您基于每个屏幕自定义屏幕是否是 modal 类型。

另外,要匹配 iOS 的默认行为, presentation: 'modal' 在 iOS 13 中引入的新 modal 演示风格。它还可以自动调整标题中的状态栏高度等以前必须手动执行的操作。此外,当屏幕设置动画时,状态栏内容的颜色会自动管理。

此前,Android 没有为 modal 设置任何特殊动画。但现在有一个从底部滑动的动画,替代了默认动画。

如果不想使用新动画,可以使用与动画相关的选项将其更改为您的喜好。要使用 React Navigation 5 中的 iOS 模式动画,请使用 TransitionPresets.ModalSlideFromBottomIOS

此外,还有一个新的演示文稿: presentation: 'transparentModal' ,使构建透明模态更加容易。有关详细信息,请参阅透明 modals 文档

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

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

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

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

以前,可以通过 headerMode=“none” 属性在堆栈导航器中隐藏 header。但是,也有一个 headerShow 选项,可以用来隐藏或显示标题,并且它支持每个屏幕的配置。

所以,与其有两种相似的方式来做同一件事情,我们选择移除 headerMode="none",并替换为 headerShown: false。要获取旧行为,请在 screenOptions中指 定headerShown: false

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

headerMode 被移到 options 中

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

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

headerMode 选项支持两个值:screenfloat

Header 现在在 iOS 上的 modal 中更高

在 modals 中,标头现在是 56dp 高,以匹配原生 iOS 风格。如果使用 useHeaderHeight 钩子来获取标头的高度,则不需要更改任何代码。

现在忽略隐藏 header 的高度

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

自定义 header 现在默认使用 'headerMode: screen'

以前,使用自定义 header 时,需要手动指定 headerMode='screen' 或自定义动画。尽管在文档中提到了这一点,但许多人还是对此感到困惑。

但现在,指定自定义 header 会自动将 headerMode 设置为 screen,因此不需要更多操作。这现在是可能的,因为 headerMode 不再是导航器的 prop,因此可以在指定自定义 header 的每个屏幕上配置它。

传递到自定义 header 的 props 被简化

以前,栈 header 接受场景和包 descriptor, navigation prop, progress 等内容的前一个场景。现在这些 props 现在做了简化,详情参见 header 文档。

如果你有一个自定义的 header ,你可能需要调整它来使用新的 props。

Header 现在使用 flexbox 进行布局

header 元素使用绝对定位进行渲染,在某些情况下效果不佳。我们现在将 flexbox 用于 header 元素,这应该会更好地工作。

这可能不会对您产生任何影响,但如果您有依赖于绝对定位的代码,您可能需要更改它。

gestureResponseDistance 选项现在是一个 number 而不是一个 object

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

iPad 中的触控板上的双指返回手势现在得到支持

在 iPad 上,可以使用两个手指在本地应用程序中执行后退手势。现在在堆栈导航器中也可以使用。

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

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

一些导出现在被移动到 element 库中

下面的导出现在位于 elements 库中,因为它们不再归堆栈导航器独有:

  • Assets
  • HeaderTitle
  • HeaderBackButton
  • HeaderBackground
  • HeaderHeightContext
  • useHeaderHeight

有关安装 elements 库的详细信息,请参见这里

Native Stack Navigator

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

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

npm

npm install @react-navigation/native-stack

Yarn

yarn add @react-navigation/native-stack

react-native-screens/native-stack 包里的破坏性变更

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

Native Stack 的 options

  • backButtonInCustomView 选项已删除,现在在需要时自动设置
  • headerCenter 选项被删除,headerLeftheaderRightheaderTitle 选项现在可以像在 Stack Navigator 中那样工作
  • headerHideBackButton 已更改为 headerBackVisible
  • headerHideShadow 已更改为 headerShadowVisible
  • headerLargeTitleHideShadow 已更改为 headerLargeTitleShadowVisible
  • headerTranslucent 已更改为 headerTransparent
  • headerBlurEffect 现在是一个单独的选项,不再是 headerStyle 中的属性
  • headerTopInsetEnabled 选项已删除,现在在必要时自动设置
  • disableBackButtonMenu 更改为 headerBackButtonMenuEnabled
  • backButtonImage 重命名为 headerBackImageSource
  • searchBar 重命名为 headerSearchBarOptions
  • replaceAnimation 重命名为 animationTypeForReplace
  • stackAnimation 重命名为 animation
  • stackPresentation 重命名为 presentation-值 push 现在称为 card
  • direction 选项被删除,现在它基于 I18nManager.isRTL 自动设置

事件

appeardisappear 事件已被删除,无论屏幕是打开还是关闭的时候,都被替换为带有 e.data.closingtransitionStarttransitionEnd 事件。

Native Stack 现在可以在 Web 上使用

以前,native-stack 只能在 Android 和 iOS 上使用。但我们还添加了基本的 web 支持,这样您就可以编写跨平台应用程序,而无需更改代码。

Bottom Tab Navigator

@react-navigation/bottom-tabs 包中有以下更改。

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

npm

npm install @react-navigation/bottom-tabs

Yarn

yarn add @react-navigation/bottom-tabs

默认情况下,在选项卡屏幕中显示 header

选项卡屏幕现在默认显示一个 header,类似于堆栈导航器中的屏幕。这避免了在每个屏幕中只为 header 而要嵌套堆栈导航器。查看 选项文档 以查看所有与 header 相关的选项。

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

当没有传递图标选项卡栏将显示问号而不是空白区域

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

tabBarOptions 属性被删除,以支持底部选项卡更灵活的 options

tabBarOptions props 被移除,选项被移到屏幕的 options 中。这使得它们可以在每个屏幕上配置。

options 列表及其新名称如下:

  • 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 来禁用自动标签定位。

旧选项仍将在出现弃用警告时继续工作。要避免出现弃用警告,请将其移至 screenOptions

tabBarVisible 选项不再存在

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

对于底部选项卡的每个屏幕配置,lazy prop 被移动到 lazy option

lazy prop 现在可以按屏幕配置,而不是为整个导航器配置。所以它从 prop 转移到了 option。要保持先前的行为,您可以在 screenOptions 中指定它以将其应用于所有屏幕。

新建 tabBarBackground 选项以指定自定义背景

新的 tabBarBackground 选项有助于向选项卡栏添加自定义背景,如图像、渐变、模糊视图等,而无需手动包装 TabBar

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

Material Top Tab Navigator

@react-navigation/material-top-tabs 包中有以下更改。

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

npm

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

Yarn

yarn add @react-navigation/material-top-tabs react-native-tab-view

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

对于 Expo 管理的项目:

npx expo install react-native-pager-view

对于普通 React Native 项目:

npm

npm install react-native-pager-view

Yarn

yarn add react-native-pager-view

Material Top Tabs 现在使用 ViewPager 而不是 Reanimated 和 Gesture Handler

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

有关更多详细信息,请参阅 react-native-tab-view 的发行说明。

tabBarOptions props 被删除,以支持更灵活的 Material Top Tabs options

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

options 列表及其新名称如下:

  • 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

对于 material top tabs 的每个屏幕配置,lazy prop 被移动到 lazy option

与底部选项卡类似,lazy prop 现在移动到 material top tabs 的 options

对于 material top tabs 的每个屏幕配置, lazyPlaceholder prop 被移动到 lazyPlaceholder option

lazyPlaceholder 属性现在移动到 material top tabs 的 options 中,以便您可以在每个屏幕的选项中配置占位符。

Material Bottom Tab Navigator

@react-navigation/material-bottom-tabs 包中有以下更改。

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

npm

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

Yarn

yarn add @react-navigation/material-bottom-tabs

Material Bottom Tab 现在使用 react-native-safe-area-context 来确认安全区域

使用 @react-navigation/material-bottom-tab 时,现在需要安装 react-native-safe-area-context(如果您还没有)。

Drawer Navigator

@react-navigation/drawer 包中有以下更改。

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

npm

npm install @react-navigation/drawer

Yarn

yarn add @react-navigation/drawer

抽屉(drawer)现在使用 Reanimated 2(如果可用)

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

您可以将 useLegacyImplementation={true} 传递给 Drawer.Navigator 来强制它始终使用旧的实现。

默认情况下,在抽屉屏幕中显示 header

选项卡屏幕现在默认显示一个 header,类似于堆栈导航器和底部选项卡导航器中的屏幕。查看其选项以查看所有与 header 相关的选项。

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

幻灯片动画现在是 iOS 上的默认设置

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

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

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

为了适应这一变化,还重命名了以下 API:

  • getIsDrawerOpenFromState -> getDrawerStatusFromState
  • useIsDrawerOpen -> useDrawerStatus
  • openByDefault -> defaultStatus

抽屉不再触发 drawerOpendrawerClose 事件

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

  • useDrawerStatus hook
  • getDrawerStatusFromState helper (e.g. - getDrawerStatusFromState(navigation.getState()))

drawerContentOptions prop 现在通过移动到抽屉 options 变得更加灵活

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

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

  • drawerPosition
  • drawerType
  • keyboardDismissMode
  • overlayColor
  • gestureHandlerProps

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

  • hideStatusBar -> drawerHideStatusBarOnOpen
  • statusBarAnimation -> drawerStatusBarAnimation
  • edgeWidth -> swipeEdgeWidth
  • minSwipeDistance -> swipeMinDistance

旧选项仍将在出现弃用警告时继续工作。要避免出现弃用警告,请将其移至 screenOptions

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

传递给 drawerContent 的回调不再在其参数中接收动画 progress 。但是,您可以使用useDrawerProgress挂钩获取当前进度值。

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

  // ...
}

// ...

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

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

对于抽屉的每个屏幕配置,将 lazy prop 移动到 lazy option

与底部选项卡类似,lazy prop 现在移动到抽屉 options 中。

Elements 库

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

npm

npm install @react-navigation/elements

Yarn

yarn add @react-navigation/elements

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

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

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

开发工具

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

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

参考

官方原文:reactnavigation.org/docs/upgrad…

❤️支持

如果本文对你有帮助,点赞👍支持下我吧,你的「赞」是我创作的动力。