React Navigation 6.0
文档现已发布在 reactnavigation.org,v5 版本的文档请见这里。
React Navigation 6 保持了与 React Navigation 5 大致相同的核心 API,您可以将其视为对 React Navigation 5 内容的进一步完善。让我们在这篇博客文章中讨论此版本的亮点。
亮点
更灵活的导航器
导航器接受许多自定义选项作为 props,这意味着我们无法根据活动屏幕自定义它们。为了实现这种程度的控制,我们需要将这些 props 移动到您可以为每个屏幕配置的 options 中。
在 React Navigation 6 中,许多这些 props 现在是屏幕 options。最显著的变化是 tabBarOptions
和 drawerContentOptions
,它们现在都位于 options
中。例如
// Before (v5)
<Tab.Navigator
tabBarOptions={{
inactiveTintColor: 'rgba(255, 255, 255, 0.5)',
activeTintColor: '#fff',
style: {
position: 'absolute',
borderTopColor: 'rgba(0, 0, 0, .2)',
},
}}
>
// After (v6)
<Tab.Navigator
screenOptions={{
tabBarInactiveTintColor: 'rgba(255, 255, 255, 0.5)',
tabBarActiveTintColor: '#fff',
tabBarStyle: {
position: 'absolute',
borderTopColor: 'rgba(0, 0, 0, .2)',
},
}}
>
有关更多详细信息,请参阅弃用部分。
元素库
我们提取了 React Navigation 中各种导航器中使用的一些组件和助手函数,并将它们发布在一个名为 @react-navigation/elements
的新包中。如果您正在构建自己的导航器,或者只是想在您的应用程序中重用某些组件,这将非常有用。
目前只导出了一小部分组件,但未来还会有更多。
简化现有功能的 API
我们在 React Navigation 6 中简化了许多 API,以解决常见的用例。例如
- 使用模态演示样式和透明模态的单个选项,通过
presentation
实现 - 自定义 header 不再需要手动设置
headerMode="screen"
useHeaderHeight
hook 现在会忽略隐藏的 header,并返回父组件中最近可见 header 的高度- 新的选项可以为标签栏设置自定义背景(例如
BlurView
),而无需使用自定义标签栏 - 新的 API 用于管理容器上的 ref (
createNavigationContainerRef
和useNavigationContainerRef
)
新的 Group
组件用于组织
Group
组件帮助您组织导航器中的屏幕,并在 Group
之间共享通用的 screenOptions
。将 screenOptions
传递给一个 group 配置该 group 内的所有屏幕以使用这些 options。您可以通过将 options
传递给每个 Screen 组件来覆盖 Group
options,类似于您在 Navigator 上使用 screenOptions
的方式。您还可以将 Group
组件嵌套在其他 Group
组件内。它们是轻量级的,并且不渲染任何内容 - 就像 fragments 一样,因此它们不会影响性能。
在此代码片段中,您可以看到我们将常规屏幕分组在一个 group 下,并将模态屏幕分组在另一个 group 下
function App() {
return (
<Stack.Navigator>
<Stack.Group>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Group>
<Stack.Group screenOptions={{ presentation: 'modal' }}>
<Stack.Screen name="CreatePost" component={CreatePostScreen} />
</Stack.Group>
</Stack.Navigator>
);
}
底部标签页和抽屉导航默认显示 Header
开发者通常希望在抽屉导航和底部标签页内的屏幕上显示 header。为此,我们必须嵌套一个提供 header 的堆栈导航器,即使它只是一个只有一个屏幕的导航器。因此,我们现在默认在抽屉导航和底部标签页的屏幕中显示 header。无需嵌套。
我们还在新的元素库中导出了一个 Header
组件,可以在您组件中的任何地方使用。
默认使用原生导航
从历史上看,React Navigation 主要基于 JS,动画和手势使用 JavaScript 在 react-native-gesture-handler
和 react-native-reanimated
或 Animated
之上编写。虽然这对许多应用程序都适用,但具有繁重屏幕的应用程序可能会受到性能不佳的影响,并且一些原生功能难以精确地重新创建(例如 iOS 上的大型 header)。因此,我们希望通过使用原生基元进行导航来解决这个问题。
在 React Navigation 5 中,我们引入了由 react-native-screens
驱动的 @react-navigation/native-stack
包,以及由 react-native-pager-view
驱动的 @react-navigation/material-top-tabs
的原生后端。
在 React Navigation 6 中,我们使 @react-navigation/native-stack
成为设置 Stack 导航的默认选择。它在 iOS 上使用 UINavigationController
,在 Android 上使用 Fragments 来实现原生导航。我们还非常注重使 @react-navigation/native-stack
的 API 与 @react-navigation/stack
对齐,以便更容易在它们之间切换。
虽然
@react-navigation/native-stack
现在在文档中用作默认选择,但它并没有取代@react-navigation/stack
。这两个包都得到了维护,并且都是您项目的有效选择。如果您目前正在使用@react-navigation/stack
,您可以继续使用它。除非您真的想迁移,否则您无需迁移到@react-navigation/native-stack
。
同样,我们将 @react-navigation/material-top-tabs
切换为默认使用 react-native-pager-view
。
更好的类型安全
React Navigation 5 的 TypeScript 支持比 React Navigation 4 好得多;但是,某些东西(例如 useNavigation
)默认情况下仍然是无类型的。
在 React Navigation 6 中,您无需注释 useNavigation
即可获得自动完成和类型检查。这可以通过使用声明合并为屏幕全局定义类型来实现
declare global {
namespace ReactNavigation {
interface RootParamList {
Home: undefined;
Profile: { userId: string };
NotFound: undefined;
}
}
}
您可以在我们的 TypeScript 文档中阅读更多相关信息。
Flipper 插件
我们新的 Flipper 插件包含与当前可用的 Redux Devtools Extensions 集成类似的功能。您可以查看所有导航操作,并在较早和较新的导航状态之间来回跳转。此外,它还包含一个用于测试您的链接配置的选项卡。
由于开发工具是从头开始构建的,因此我们现在可以自由添加新功能,以便将来更容易进行调试。
Flipper 插件相对于 Redux Devtools Extension 的一个优势是它不需要 Chrome Debugger 即可工作。由于 Chrome Debugger 有时会影响性能,甚至可能改变行为,我们认为这是一个更可靠的解决方案。
有关更多详细信息,请参阅设置指南。请注意,Expo 管理的应用程序中的 Flipper 支持需要自定义开发客户端,并且在撰写本文时,它在 Expo Go 中不起作用。
升级
虽然 React Navigation 6 没有引入与 React Navigation 5 相同规模的更改,但仍然存在一些重大更改。但是,可以混合使用 React Navigation 5 和 React Navigation 6 中的包(有一些注意事项),以便您可以逐步升级包。
有关更改的完整列表和更多详细信息,请参阅升级指南。
赞助我们
如果 React Navigation 帮助您为客户交付价值,如果您可以赞助我们,那将非常棒。赞助将帮助我们更快地朝着构建最佳跨平台导航库的目标迈进,并继续为我们在 GitHub issues 中的错误报告提供及时支持。