跳到主要内容

React Navigation 5.0 - 导航新方式

·7 分钟阅读
Satyajit Sahoo
核心团队
Michał Osadnik
Michał Osadnik
核心团队

整整两年前,我们发布了 React Navigation 的第一个稳定版本。在这段时间里,该库一直在积极开发,添加了许多新功能和错误修复。React Navigation 的本质在于,它不仅是一个由个别程序员根据自身需求进行调整的项目,而且是一个作为一个整体的社区项目,因此强调了通用性、可扩展性以及在存在此类需求时重新考虑假设的趋势。正因如此,该库经历了增量式和完全重组式的形态转变。

这使得 React Navigation 成为 React Native 中最流行的导航解决方案之一,我们对此感到无比自豪。

今天,我们想要将过去六个月中发生的这个项目的愿景和重大重构标记为稳定版。可以说,这一重大变化关系到核心库以及 API,API 已经得到开发并变得更加动态。

亮点

基于组件的配置

在以前版本的 React Navigation 中,我们过去使用 createXNavigator 函数和 static navigationOptions 静态配置导航器。在 React Navigation 5 中,所有配置都发生在组件内部并且是动态的。

示例

function App() {
return (
<Stack.Navigator initialRouteName="home">
<Stack.Screen name="settings" component={Settings} />
<Stack.Screen
name="profile"
component={Profile}
options={{ title: 'John Doe' }}
/>
</Stack.Navigator>
);
}

这意味着我们可以访问 props、state 和 context,并且可以动态更改导航器的配置!

我们想强调这是最重要的变化。这似乎只是 API 的差异。实际上,它需要重新考虑在先前版本的 React Navigation 开发过程中做出的许多假设。从以前版本中已知的静态 API 似乎是更容易和更明显的选择。在当前版本中,导航配置与 React 社区中的所有模式一致。这使得有必要重写库的核心,这使我们不仅在这方面而且在许多其他方面都进行了改进。

新 Hook

Hook 非常适合有状态逻辑和代码组织。现在我们有几个用于常见用例的 Hook

从组件更新选项

我们在 navigation prop 上添加了一个新的 setOptions 方法,以使配置屏幕导航选项比其 static navigationOptions 前身更直观。它使我们能够轻松地根据 props、state 或 context 设置屏幕选项,而无需处理参数。我们可以随时调用它来配置屏幕,而不是使用静态选项。

navigation.setOptions({
headerRight: () => (
<DoneButton
onPress={async () => {
await saveNote();
navigation.replace('Notes');
}}
/>
),
});

它可以用于诸如在 header 中添加一个需要与屏幕状态交互的按钮之类的事情。

新的主题 API

在 React Navigation 中,我们有基本的主题支持,您可以在其中指定是使用浅色主题还是深色主题。如果不使用额外的代码或重复,则不易自定义内置组件(如 header、tab bar 等)使用的颜色。

现在,我们改进了 主题系统,以便更轻松地进行自定义。可以提供一个主题对象,其中包含您想要的背景色、强调色等,它将自动更改所有导航器的颜色,而无需任何额外的代码。

const MyTheme = {
dark: false,
colors: {
primary: 'rgb(255, 45, 85)',
background: 'rgb(242, 242, 242)',
card: 'rgb(255, 255, 255)',
text: 'rgb(28, 28, 30)',
border: 'rgb(199, 199, 204)',
},
};

具有 TypeScript 的一流类型

新版本已从头开始使用 TypeScript 编写。我们现在获得了第一流的自动完成和类型检查。

TypeScript in action

我们还为内置方法和选项提供了 JSDoc,因此您可以直接在编辑器中获取它们的描述。有关如何使用它的更多详细信息,请参阅 我们的 typescript 文档

Redux DevTools 集成

如果您使用 React Native DebuggerRedux Devtools Extension,您可以在 devtools 中看到导航操作以及当前的导航状态。它还支持时间旅行调试!

Redux Devtools in action

您无需在您的应用程序中使用 Redux 即可使其工作,并且它无需任何额外的设置即可工作!

原生 Stack Navigator

传统上,我们用 JavaScript 编写导航器以获得更大的可定制性。它适用于许多用例,但有时您想要确切的原生感觉和原生导航的性能。现在,我们添加了一个新的原生 stack navigator,它使用原生导航原语进行导航,使用了 react-native-screens 库。在底层,它只使用原生组件,这对于原生开发来说可能是显而易见的选择,并且在大多数情况下可能是不错的选择。

Native Stack on Android Native Stack on iOS

Material top tab navigator 的原生后端

与原生 stack 类似,我们还为基于 react-native-viewpagerScrollView 的 Material top tab navigator 提供了新的后端

import ViewPagerAdapter from 'react-native-tab-view-viewpager-adapter';

// ...

<Tab.Navigator pager={props => <ViewPagerAdapter {...props} />}>
{...}
</Tab.Navigator>

import { ScrollPager } from 'react-native-tab-view';

// ...

<Tab.Navigator pager={props => <ScrollPager {...props} />}>
{...}
</Tab.Navigator>

其他改进

除了这些较大的改进之外,还有一些较小的改进,以适应更多的用例并使某些任务更容易完成

  • 改进了抽屉导航器,使自定义抽屉侧边栏内容更容易和更灵活。
  • 用于 reset 操作 的更简单的 API,您可以在其中直接传递新状态,而不是操作链。
  • 更可靠的 focusblur 事件,以了解屏幕的焦点状态何时更改。
  • InteractionManager 集成,以延迟任务直到动画完成。
  • 通过 react-native-safe-area-context 更好地处理安全区域。

升级

这是一个大型版本,虽然嵌套等基本概念相同,但新 API 在很大程度上与以前的 API 不兼容。我们知道升级您的代码库可能是一个挑战。因此,我们将继续支持 React Navigation 4 进行错误修复。我们将接受贡献并使其与最新的 React Native 版本兼容。旧代码现在将位于 GitHub 上的 4.x 分支中。

我们建议您使用新版本启动新项目,以便您可以利用新的 API 和新功能。

我们编写了一个 升级指南,它将概述已更改的内容以及如何将旧 API 和概念适应新 API。

给 alpha 用户的注意事项

如果您在 React Navigation 5 处于 alpha 阶段时使用了它,则在升级时可能需要检查以下更改

  • 如果您已将 @react-navigation/core 添加到您的依赖项中,请将其删除,并将所有从 @react-navigation/core 的导入替换为 @react-navigation/native
  • 如果您导入了 NavigationNativeContainer,请将其更改为 NavigationContainer,如果您使用的是 NavigationContainer,请将其更改为 BaseNavigationContainer
  • 如果您配置了深度链接,则嵌套的配置格式已更改。请查看 深度链接文档 以了解详细信息。

感谢这些杰出人士

如果没有这些杰出人士,React Navigation 5 将不可能实现。非常感谢 Michał Osadnik 与我一起从想法到实现都在这个项目中工作,感谢 Brent Vatne 的想法、鼓励以及来自 Expo 的资助,感谢 Wojciech LewickiJakub Gonet 改进文档,并致力于深度链接支持,感谢 Krzysztof MagieraSoftware Mansion 及其很棒的库,核心功能依赖于这些库和贡献,感谢 Janic Duplessisreact-native-safe-area-context

此外,我想提及社区对构建这个项目的影响有多么重要。没有您,没有您的支持,没有您测试和应用库的后续版本的意愿,这一切都不可能实现,尽管按名称提到了少数人,但在任何阶段我们都没有忘记这是一项社区活动,并将响应社区的需求。我们非常感谢有机会从事这样一个非凡的项目,它促进了大量用户的工作。

再次感谢,并希望您会发现此版本很有用。