跳到主要内容

3.0 版本候选版

·8 分钟阅读
Brent Vatne
核心团队

我们很高兴地宣布今天发布 3.0 版本的候选版!

这是 React Navigation 首次依赖于 React Native 核心之外的原生模块的版本:它现在依赖于 react-native-gesture-handler。这个库提供了一组出色的原语,用于利用操作系统的原生手势 API,并使我们能够修复堆栈和抽屉导航器中的各种问题。React Navigation 还依赖于 react-native-screens,但如果您不想使用它,则无需安装原生模块(我们即将发布一篇博客文章,解释 react-native-screens 是什么以及您可能想要使用它的原因,或者您可以观看库作者的这个演讲)。

我们没有完成我们想要在此版本中实现的所有功能,但我们也不想进一步拖延它,因为我们预计您会希望立即开始使用它 - 该版本包括性能改进、错误修复、人体工程学改进、一些方便的新功能,以及内部结构的重新组织,以改进对 Web 作为 React Navigation 目标的的支持。

让我们开始使用 react-navigation 3.0。

安装

首先,使用您喜欢的包管理器安装库:yarn add react-navigation@^3.0.0-rc.0

接下来,安装 react-native-gesture-handler。如果您使用 Expo,则无需在此处执行任何操作,它已包含在 SDK 中。否则:yarn add react-native-gesture-handler && react-native link

可选地,您可以安装 react-native-screens。如果您使用 Expo,则无需在此处执行任何操作,它已包含在 SDK 30 及更高版本中。否则,请按照 react-native-screens 上的 README 中的说明进行操作。

警告:如果您在项目中手动安装了任何导航器,例如 react-navigation-material-bottom-tabs,则需要将这些导航器更新到与 3.0.0 兼容的版本。对于 react-navigation-material-bottom-tabs,1.0.0-alpha.2 是兼容的。

重大更改

当您在更新后首次运行您的应用程序时,它将无法工作,因为 react-navigation@^3 要求您向根导航器添加一个应用程序容器。一旦您将其就位,您可能会注意到您的导航选项未按预期应用 - 这是由于导航器配置中的 navigationOptions 已重命名为 defaultNavigationOptions。如果您使用抽屉,您可能会注意到它感觉更快,但如果您依赖于非活动屏幕被卸载,您会感到惊讶。有关这些更改以及如何更新您的应用程序以使其与以前一样好(可能更好)的更多详细信息如下。

根导航器需要显式应用程序容器

过去,任何导航器都可以充当应用程序顶级的导航容器,因为它们都包裹在“导航容器”中。导航容器(现在称为应用程序容器)是一个高阶组件,它维护应用程序的导航状态并处理与外部世界的交互,以将链接事件转换为导航操作等等。

import {
createStackNavigator,
createAppContainer
} from 'react-navigation';
const MainNavigator = createStackNavigator({...});
const App = createAppContainer(MainNavigator);

这应该是一个简单的更改 - 在应用程序的根目录中导入 createAppContainer 并使用它来包装根导航器。

警告:如果您有任何自定义导航器,您可能使用了 createNavigationContainer,您现在可以删除它,因为它仅在应用程序的根目录中使用,并由用户提供。

导航器配置中重命名的 navigationOptions

在配置导航器时,传入该导航器内部屏幕的默认导航选项通常很有用。例如,在堆栈中,您可能希望为每个屏幕设置背景颜色和色调颜色。以前,您会这样写

const Home = createStackNavigator(
{
Feed: ExampleScreen,
Profile: ExampleScreen,
},
{
navigationOptions: {
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#000',
},
},
}
);

从本版本开始,像这样的导航器配置中的 navigationOptions 已重命名为 defaultNavigationOptions

const Home = createStackNavigator(
{
Feed: ExampleScreen,
Profile: ExampleScreen,
},
{
defaultNavigationOptions: {
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#000',
},
},
}
);

有时您需要配置导航器本身的 navigationOptions。通常你会这样做

Home.navigationOptions = { tabBarLabel: 'Home!' };

从本版本开始,您可以在导航器配置中使用 navigationOptions 来代替。

const Home = createStackNavigator(
{
Feed: ExampleScreen,
Profile: ExampleScreen,
},
{
defaultNavigationOptions: {
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#000',
},
},
navigationOptions: {
tabBarLabel: 'Home!',
},
}
);

const Tabs = createBottomTabNavigator({ Home });

在 Snack 上查看此示例.

很抱歉让您在代码中搜索并重命名一些字符串,希望此更改使代码更具可读性,并且对未来的新用户更直观。

抽屉现在默认将非活动标签页保留在内存中

以前,当使用抽屉导航器时,屏幕在不活动时会卸载,当您切换回它们时,您需要重新渲染整个内容。在标签页中,这些标签页会按预期保留在内存中,因此一旦您切换到屏幕一次,再次返回那里会更快,并且您不会在滚动视图中丢失您的位置或任何东西。抽屉现在表现相同,但如果您愿意,可以通过在抽屉导航配置中传入 unmountInactiveRoutes: true 来恢复旧的行为。

新功能

  • react-navigation 现在导出 ScrollViewFlatListSectionList,当您点击活动标签页时,它们会滚动到顶部,正如您从原生标签栏所期望的那样。
  • 抽屉除了您从典型的 Android 抽屉所期望的默认“front”行为外,还支持另外两种类型:back 和 slide。
  • 您现在可以在路由定义中提供默认参数
const Store = createStackNavigator({
Playstation: { screen: ProductScreen, params: { product: 'Playstation' } },
Xbox: { screen: ProductScreen, params: { product: 'Xbox' } },
});
  • react-navigation-hooks 中对 Hooks 的基本支持
  • headerBackgroundTransitionPreset: 'toggle' | 'fade' | 'translate' 让您可以选择如何在屏幕之间过渡您的自定义 headerBackground 组件。
  • 添加选项以选择加入/退出在过渡期间可见的堆栈卡片叠加层和阴影:cardShadowEnabled 默认为 truecardOverlayEnabled 默认为 false
  • 从 react-navigation-stack 和 react-navigation-drawer 导出 StackGestureContextDrawerGestureContext,因此您可以将相应手势的 ref 与其他手势处理程序一起使用(例如:GestureInteraction.js)。

各种修复和改进

  • 通过从整个卡片中删除阴影并仅在需要它的切片上渲染阴影,大大提高了堆栈过渡性能。卡片不透明度也不再直接动画化,而是在顶部放置一个叠加层以创建类似的效果,但具有更好的性能。
  • 修复了堆栈的长期存在的问题,这些问题导致在某些模式下快速导航时静默地重新挂载屏幕:react-navigation/issues/415
  • 支持模态中的反向手势。
  • 堆栈卡片手势使用 react-native-gesture-handler 和原生驱动程序,因此手势在 UI 线程上运行(除非手势结束,否则它会回调到 JS)。
  • 修复了抽屉导航器的各种问题,包括围绕嵌套的问题(react-navigation/issues/4154)和打开/关闭触发的错误(例如:react-navigation/issues/5146)。

生态系统和 Web 支持

React Navigation 3.0 为 React Navigation 生态系统带来了一些重要的变化:该项目现在分布在多个存储库和软件包中,我们正在开发一个令人兴奋的新过渡器,并且核心最终对客户端和服务器上的 Web 应用程序提供了 первоклассный 支持!

独立项目

React Navigation 一直是一组松散耦合的导航组件:Stack、Tabs、Drawer 等。但到目前为止,它们一直存在于主导航存储库中,这很难维护。人们经常难以使用这些组件的不同版本,或者他们想为自己的应用程序 fork 它们。

在 v3 中,我们所有的主要软件包和存储库都已分离。我们的新 NPM 组织中有以下核心软件包

  • @react-navigation/core - 定义我们模式的原语和实用程序,以及多个路由器
  • @react-navigation/native - React Native 应用程序上的导航器的容器和支持。主 react-navigation 软件包中的 createAppContainer 实际上来自此软件包。
  • @react-navigation/web - Web 浏览器应用程序容器,以及用于服务器渲染的实用程序

此外,我们已将社区维护的组件发布为独立的存储库和软件包

  • react-navigation-stack
  • react-navigation-tabs
  • react-navigation-drawer
  • react-navigation-transitioner
  • react-navigation-hooks

为了尽可能简化体验,react-navigation 软件包将继续受到支持,并将像以前一样包含大多数上述组件。

Web 支持

既然 React Navigation 的核心可以在 React Native 之外使用,我们可以为在 Web 上使用 React.js 的任何人提供 первоклассный Web 支持,包括那些不想使用 react-native-web 的人。

这是一个 Web 应用程序示例,演示了新的 createBrowserApp 容器和内置的 Link 组件

import { createSwitchNavigator } from "@react-navigation/core";
import { createBrowserApp, Link } from "@react-navigation/web";

class Home extends React.Component {
static path = "";
static navigationOptions = {
title: "Home",
};
render () {
return (
<div>
<h2>Home Screen</h2>
<Link toRoute="Profile" params={{ name: "Brent", view: "photos" }}>
Brent's photos
</Link>
</div>
);
}
}
class Profile extends React.Component {
static path = "/profile/:name";
...
}

const AppNavigator = createSwitchNavigator({
Home,
Profile,
});

const App = createBrowserApp(AppNavigator);

export default App;

上面的 Link 标签将呈现为:<a href=``"``/profile/Brent?view=photos``"``>Brent 的照片</a>

在此处查看使用 Create React App 的简单 Web 应用程序here。或查看 这个 razzle 应用程序,了解更复杂的示例,包括服务器渲染。


感谢阅读,请将您遇到的任何问题发布到 react-navigation/issues