旧金山聚会回顾
上周我有机会参加了在 Zynga 旧金山办公室举办的 React Native 聚会。大约有 200 人参加了这次活动,这为我提供了一个绝佳的机会,可以与我附近对 React Native 感兴趣的其他开发者见面。
我特别感兴趣的是了解 Zynga、Netflix 和 Airbnb 等公司如何使用 React 和 React Native。当晚的议程如下:
- React 中的快速原型设计
- 为 React Native 设计 API
- 弥合差距:在现有代码库中使用 React Native
但首先,活动以简短的介绍和最近新闻的回顾开始。
- 您知道 React Native 现在是 GitHub 上排名第一的 Java 代码库 吗?
- rnpm 现在是 React Native 核心的一部分!您现在可以使用
react-native link
代替rnpm link
来 安装具有原生依赖项的库。 - React Native 聚会社区发展迅速!现在全球有超过 4800 名开发者参与了各种 React Native 聚会小组。
如果 其中一个聚会 在您附近举行,我强烈建议您参加!
Zynga 的 React 快速原型设计
第一轮新闻之后,Zynga(我们当晚的东道主)进行了简短的介绍。Abhishek Chadha 谈到了他们如何使用 React 快速为移动设备创建新的体验原型,并演示了一个类似于 Draw Something 的应用的快速原型。他们使用与 React Native 类似的方法,通过桥接提供对原生 API 的访问。当 Abhishek 使用设备的摄像头拍摄观众的照片,然后在某人的头上画了一顶帽子时,就展示了这一点。
Netflix 的 React Native API 设计
接下来是当晚的第一个特色演讲。Netflix 高级软件工程师 Clarence Leung 发表了关于为 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 代码的更改将需要三个单独的拉取请求,所有这些都需要仔细落地。为了避免冲突,如果自构建开始以来 master 发生了更改,则 CI 将无法将更改落地回 Android 和 iOS 存储库。这将在提交频率较高的日子(例如,在发布新版本时)导致长时间延迟。
Airbnb 后来转向了单存储库方法。幸运的是,这已经在考虑之中,一旦 Android 和 iOS 团队对使用 React Native 感到满意,他们很乐意加速向单存储库的迁移。
这解决了他们使用分离式仓库方法时遇到的大多数问题。Leland 指出,这确实会导致版本控制服务器的负载增加,这对小型公司来说可能是一个问题。
导航问题
Leland 演讲的后半部分重点关注了一个我非常关心的主题:React Native 中的导航问题。他谈到了 React Native 中大量存在的导航库,包括官方和第三方库。NavigationExperimental 被提及,似乎很有前景,但最终并不适合他们的用例。
事实上,现有的导航库似乎都不适合于 Brownfield 应用。Brownfield 应用要求导航状态完全由原生应用拥有。例如,如果用户会话在显示 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 修复任何问题,而无需通过 App Store,并且他们的工程师喜欢 Live Reload,因为他们不必在每次进行微小更改后等待原生应用重新构建。
结束语
活动以一些额外的 React Native 新闻结束
- Deco 宣布了他们的 React Native 展示,并邀请大家将他们的应用添加到列表中。
- 最近的 文档大修 获得了认可!
- Deco IDE 的创建者之一 Devin Abbott 将教授一门介绍性的 React Native 课程。
Meetup 为社区中的其他开发者提供了良好的交流和学习机会。我期待未来参加更多 React Native Meetup。如果您参加了其中一个,请留意我,并告诉我我们如何才能让 React Native 更好地为您服务!