跳至主要内容

旧金山聚会回顾

·阅读时长 9 分钟
Héctor Ramos
Héctor Ramos
Facebook 前开发者布道师

上周我有机会参加了在 Zynga 旧金山办公室举办的 React Native 聚会。大约有 200 人参加,这是一个与附近其他对 React Native 感兴趣的开发者见面的好机会。

我特别感兴趣的是了解 Zynga、Netflix 和 Airbnb 等公司如何使用 React 和 React Native。当晚的议程如下

  • React 中的快速原型设计
  • 为 React Native 设计 API
  • 弥合差距:在现有代码库中使用 React Native

但首先,活动以简短的介绍和最近新闻的回顾开始

如果 其中一个聚会 靠近您,我强烈建议您参加!

Zynga 中的 React 快速原型设计

第一轮新闻之后,Zynga(我们当晚的东道主)进行了简短的介绍。Abhishek Chadha 谈到了他们如何使用 React 在移动设备上快速构建新体验的原型,并演示了一个类似于 Draw Something 应用的快速原型。他们使用了与 React Native 类似的方法,通过桥接提供对原生 API 的访问。当 Abhishek 使用设备的摄像头拍摄观众的照片,然后在某人的头上画了一顶帽子时,这一点得到了证明。

Netflix 中为 React Native 设计 API

接下来,是当晚的第一个特色演讲。Clarence Leung,Netflix 的高级软件工程师,发表了关于为 React Native 设计 API 的演讲。首先,他指出了人们可能需要处理的两种主要类型的库:组件(例如标签栏和日期选择器)以及提供对原生服务的访问的库(例如相机胶卷或应用内支付)。在为 React Native 构建库时,有两种方法可以采用

  • 提供平台特定的组件
  • 一个跨平台的库,为 Android 和 iOS 提供类似的 API

每种方法都有自己的考虑因素,由您决定哪种方法最适合您的需求。

方法 #1

作为平台特定组件的一个例子,Clarence 谈到了来自 React Native 核心的 DatePickerIOS 和 DatePickerAndroid。在 iOS 上,日期选择器作为 UI 的一部分呈现,可以轻松地嵌入到现有的视图中,而在 Android 上,日期选择器以模态方式呈现。在这种情况下,提供单独的组件是有意义的。

方法 #2

另一方面,照片选择器在 Android 和 iOS 上的处理方式相似。有一些细微的差别——例如,Android 不会像 iOS 使用自拍那样将照片分组到文件夹中——但这些差别很容易使用 if 语句和 Platform 组件来处理。

无论您选择哪种方法,最好尽量减少 API 表面并构建特定于应用程序的库。例如,iOS 的应用内购买框架支持一次性购买、消耗性购买以及可续订订阅。如果您的应用程序只需要支持消耗性购买,您可以在跨平台库中放弃对订阅的支持。

在 Clarence 的演讲结束时,有一个简短的问答环节。其中一个有趣的细节是,在 Netflix 为这些库编写的 React Native 代码中,大约 80% 可以在 Android 和 iOS 之间共享。

弥合差距,在现有代码库中使用 React Native

当晚的最后一场演讲是由来自 Airbnb 的 Leland Richardson 进行的。演讲的重点是在现有代码库中使用 React Native。我已经知道使用 React Native 从头开始编写一个新应用程序有多么容易,因此我非常有兴趣了解 Airbnb 在其现有的原生应用程序中采用 React Native 的经验。

Leland 从谈论绿地应用和棕地应用开始。绿地表示在无需考虑任何先前工作的情况下启动项目。这与棕地项目形成对比,在棕地项目中,您需要考虑现有项目的必要条件、开发流程以及所有团队的不同需求。

当您在处理绿地应用时,React Native CLI 为 Android 和 iOS 设置了一个单一的存储库,并且一切正常。在 Airbnb 使用 React Native 时遇到的第一个挑战是 Android 和 iOS 应用各自都有自己的存储库。多存储库的公司在采用 React Native 之前需要克服一些障碍。

为了解决这个问题,Airbnb 首先为 React Native 代码库设置了一个新的存储库。他们使用他们的持续集成服务器将 Android 和 iOS 存储库镜像到这个新的存储库中。在运行测试并构建 bundle 后,构建工件将同步回 Android 和 iOS 存储库。这使得移动工程师能够在不更改其开发环境的情况下处理原生代码。移动工程师不需要安装 npm、运行打包器或记住构建 JavaScript bundle。编写实际 React Native 代码的工程师不必担心跨 Android 和 iOS 同步他们的代码,因为他们直接在 React Native 存储库上工作。

这确实带来了一些缺点,主要是在于它们无法进行原子更新。需要同时修改原生代码和 JavaScript 代码的变更需要三个单独的 Pull Request,并且所有这些都需要谨慎地合并。为了避免冲突,如果在构建开始后 master 分支发生了变化,CI 将无法将变更合并回 Android 和 iOS 代码库。这会在提交频率很高的时候(比如发布新版本的时候)造成长时间的延迟。

Airbnb 后来转向了单体仓库(mono repo)的方式。幸运的是,这已经在考虑之中了,并且一旦 Android 和 iOS 团队习惯了使用 React Native,他们也乐于加速向单体仓库的迁移。

这解决了他们在使用分离仓库方式时遇到的绝大多数问题。Leland 指出,这确实会给版本控制服务器带来更大的压力,这对规模较小的公司来说可能是一个问题。

导航问题

Leland 演讲的后半部分重点关注了一个对我来说非常重要的主题:React Native 中的导航问题。他谈到了 React Native 中大量的导航库,包括官方和第三方。NavigationExperimental 被认为很有希望,但最终并不适合他们的用例。

事实上,现有的导航库似乎都不适用于遗留应用(brownfield apps)。遗留应用要求导航状态完全由原生应用拥有。例如,如果用户会话在呈现 React Native 视图时过期,原生应用应该能够接管并根据需要呈现登录屏幕。

Airbnb 还希望避免在过渡过程中用 JavaScript 版本替换原生导航栏,因为这种效果可能会让人感到突兀。最初,他们将自己限制在模态呈现的视图上,但当他们希望在应用中更广泛地采用 React Native 时,这显然就成了一个问题。

他们决定需要自己的库。该库名为 airbnb-navigation。该库尚未开源,因为它与 Airbnb 的代码库紧密相关,但他们希望在今年年底发布它。

我不会详细介绍该库的 API,但以下是一些关键要点

  • 必须提前预注册场景(scenes)
  • 每个场景都在其自己的 RCTRootView 中显示。它们在每个平台上都以原生方式呈现(例如,在 iOS 上使用 UINavigationController)。
  • 场景中的主要 ScrollView 应该包装在一个 ScrollScene 组件中。这样做可以让你利用原生的行为,比如在 iOS 上点击状态栏滚动到顶部。
  • 场景之间的过渡由原生处理,无需担心性能问题。
  • Android 返回按钮自动支持。
  • 他们可以通过 Navigator.Config 无 UI 组件利用基于视图控制器的导航栏样式。

还有一些需要考虑的事项

  • 导航栏在 JavaScript 中不容易自定义,因为它是一个原生组件。这是有意为之的,因为使用原生导航栏是这种类型的库的硬性要求。
  • 每当通过桥传递 ScreenProps 时,都需要对其进行序列化/反序列化,因此如果在此处发送过多数据,则需要注意。
  • 导航状态由原生应用拥有(也是库的硬性要求),因此像 Redux 这样的东西无法操作导航状态。

Leland 的演讲之后还进行了问答环节。总的来说,Airbnb 对 React Native 非常满意。他们有兴趣使用 Code Push 修复任何问题,而无需通过 App Store,并且他们的工程师喜欢 Live Reload,因为他们不必在每次进行微小更改后都等待原生应用重新构建。

结束语

活动以一些额外的 React Native 新闻结束

  • Deco 宣布了他们的 React Native 展示,并邀请大家将他们的应用添加到列表中。
  • 最近的 文档大修 获得了认可!
  • Deco IDE 的创建者之一 Devin Abbott 将教授一门 React Native 入门 课程

聚会提供了一个很好的机会,可以与社区中的其他开发者见面并学习。我期待着将来参加更多的 React Native 聚会。如果你参加了其中一个聚会,请留意我,并告诉我我们如何才能让 React Native 更好地为你服务!