旧金山交流会回顾
上周我有幸参加了在 Zynga 旧金山办公室举行的 React Native 交流会。约 200 人参加了会议,这是一个很好的机会,可以结识附近同样对 React Native 感兴趣的开发者。
我特别有兴趣了解 React 和 React Native 在 Zynga、Netflix 和 Airbnb 等公司中的使用情况。当晚的议程如下:
- React 中的快速原型开发
- 为 React Native 设计 API
- 弥合差距:在现有代码库中使用 React Native
但首先,活动以一个简短的介绍和近期新闻的快速回顾拉开序幕
- 您知道 React Native 现在是 GitHub 上排名第一的 Java 仓库吗?
- rnpm 现已成为 React Native 核心的一部分!您现在可以使用
react-native link
代替rnpm link
来安装带有原生依赖项的库。 - React Native 交流会社区正在快速发展!全球各地有各种 React Native 交流会小组,现在共有超过 4,800 名开发者。
如果这些交流会之一在您附近举行,我强烈推荐参加!
Zynga 的 React 快速原型开发
第一轮新闻发布后,由当晚的主办方 Zynga 进行了简短介绍。Abhishek Chadha 谈到了他们如何使用 React 快速在移动端创建新体验的原型,并演示了一个类似“你画我猜”应用的快速原型。他们采用了与 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 首先谈到了全新应用(greenfield apps)与遗留应用(brownfield apps)。全新应用意味着无需考虑任何先前工作即可启动项目。这与遗留项目形成对比,遗留项目需要考虑现有项目的需求、开发流程以及所有团队的各种需求。
当您开发全新应用时,React Native CLI 会为 Android 和 iOS 设置一个单一仓库,一切都正常工作。Airbnb 使用 React Native 面临的第一个挑战是 Android 和 iOS 应用各自拥有独立的仓库。多仓库公司在采用 React Native 之前会遇到一些障碍。
为了解决这个问题,Airbnb 首先为 React Native 代码库设置了一个新仓库。他们使用持续集成服务器将 Android 和 iOS 仓库镜像到这个新仓库中。测试运行并构建完成打包后,构建产物会同步回 Android 和 iOS 仓库。这使得移动工程师可以在不改变其开发环境的情况下处理原生代码。移动工程师无需安装 npm、运行打包器,或记住构建 JavaScript 包。编写实际 React Native 代码的工程师无需担心其代码在 Android 和 iOS 之间同步的问题,因为他们直接在 React Native 仓库中工作。
这确实带来了一些缺点,主要是他们无法进行原子更新。需要原生代码和 JavaScript 代码组合的更改将需要三个独立的拉取请求,所有这些都必须小心地合并。为了避免冲突,如果主分支在构建开始后发生更改,CI 将无法将更改合并回 Android 和 iOS 仓库。这会在提交频率高的日子(例如发布新版本时)造成长时间延迟。
Airbnb 此后已转向单体仓库(mono repo)方法。幸运的是,这已经在此前考虑之中,一旦 Android 和 iOS 团队对使用 React Native 感到满意,他们便乐于加速向单体仓库的迁移。
这解决了他们使用拆分仓库方法时的大部分问题。Leland 确实指出,这会给版本控制服务器带来更高的压力,这对于较小的公司来说可能是一个问题。
导航问题
Leland 演讲的后半部分集中在我很关心的一个话题:React Native 中的导航问题。他谈到了 React Native 中大量的导航库,包括第一方和第三方库。NavigationExperimental 被提及为一个看似有前景但最终不适合他们用例的方案。
事实上,现有的导航库似乎都不太适用于遗留应用。遗留应用要求导航状态完全由原生应用拥有。例如,如果用户会话在 React Native 视图显示期间过期,原生应用应该能够接管并根据需要显示登录屏幕。
Airbnb 还希望避免在过渡期间用 JavaScript 版本替换原生导航栏,因为这种效果可能会很突兀。最初他们将自己限制在模态呈现的视图上,但这显然在他们的应用中更广泛地采用 React Native 时带来了问题。
他们决定需要一个自己的库。这个库名为 airbnb-navigation
。该库尚未开源,因为它与 Airbnb 的代码库紧密耦合,但他们希望能在今年年底前发布它。
我不会详细介绍这个库的 API,但以下是一些主要收获:
- 必须提前预注册场景
- 每个场景都在其自己的
RCTRootView
中显示。它们在每个平台上以原生方式呈现(例如,iOS 上使用UINavigationController
)。 - 场景中的主要
ScrollView
应该封装在ScrollScene
组件中。这样做可以利用原生行为,例如在 iOS 上点击状态栏滚动到顶部。 - 场景之间的过渡由原生处理,无需担心性能问题。
- Android 返回按钮自动支持。
- 他们可以通过 Navigator.Config 无 UI 组件利用基于视图控制器的导航栏样式。
还需要牢记一些注意事项
- 导航栏在 JavaScript 中不易定制,因为它是一个原生组件。这是有意为之,因为使用原生导航栏是这类库的硬性要求。
- ScreenProps 在通过桥接器发送时必须进行序列化/反序列化,因此如果发送过多数据,则必须小心谨慎。
- 导航状态由原生应用拥有(这也是该库的硬性要求),因此像 Redux 这样的工具无法操作导航状态。
Leland 的演讲之后也进行了一个问答环节。总的来说,Airbnb 对 React Native 感到满意。他们有兴趣使用 Code Push 来修复任何问题而无需通过应用商店,而且他们的工程师喜欢 Live Reload,因为每次小改动后他们不必等待原生应用重新构建。
总结
活动以一些额外的 React Native 新闻结束
- Deco 宣布了他们的React Native 展示,并邀请大家将自己的应用添加到列表中。
- 最近的文档大修获得了赞扬!
- Deco IDE 的创建者之一 Devin Abbott 将教授一门React Native 入门课程。
交流会提供了与社区中其他开发者见面和学习的好机会。我期待未来能参加更多 React Native 交流会。如果您能参加其中一个,请留意我,并告诉我我们如何能让 React Native 更好地为您服务!