人们把React Native看作是一次编写随处运行的一个解决方案,理论上可以加快那些需要同时为iOS和Android平台编写的app的开发速度,同时让web开发者也能轻松编写本地应用,但是 React Native是你下个项目的最佳选择吗?
什么是React Native
React Native是当前流行的同名web库React的原生版本,它的主要目的是把React的强大带到本地开发中。
React Native控件是纯粹,无副作用的函数,能在任意时刻返回视图的效果。因此更容易写出状态无关的视图,因为你不需要在状态改变的时候关注视图的更新,framework已经为你做了这件事情。UI的渲染实际使用的是本地视图,所以最终的用户体验并不会像那些只是在WebView里渲染web控件的解决方案那样糟糕。
我们是如何研究React Native的
评价一项新技术的最佳方法是使用它。我们召集了一个4个iOS和Android原生开发者的团队去策划与研究React Native。这里是我们的行动计划:
1、创建一个运行在 iOS和Android双平台上的推特客户端。
2、衡量代码的可复用性
3、评估最终app的外观和感受
4、研究第三方库的成熟度
5、采访当前的 react native开发者
6、阅读官方文档
7、查看核心功能的源码
我们创建的推特iOS和安卓客户端的源码在Spikes里面。
repo:https://github.com/novoda/spikes/tree/master/ReactNative/ReactTwitter
React Native的代价
项目设置
关于如何配置测试环境的文档相当贫乏,而且基本是过时的。结果我们花了4天的时间才成功运行了所有的测试。虽然我们之前的确没有跑JavaScript测试的经验,但是我们还是发现设置测试环境所付出的努力过于夸张。也有一些其它的技巧,但是多数都会导致兼容问题。
IDE
推荐使用的IDE是Atom,以及在其之上的插件Nuclide,Nuclide添加了对 React Native开发和静态分析工具Flow的支持。对于普通的JavaScript开发来说,也许这是一个好的编辑器,但是我们发现它跟我们习惯了的IDE如 Xcode 和 Android Studio比起来还是落后了很多。比如,对于最基本的refactor它都不支持,这可能会降低开发速度。
速度
作为原生开发者,我们发现React Native的学习曲线非常陡峭,要适应此框架上的开发,可能得花上一个月的时间。对于已经熟悉JavaScript开发,Redux, flow layout以及甚至于React的人来说,上手 React Native要快得多。
NATIVE CODING
有些特定的功能无法仅仅通过JavaScript实现,需要原生代码:
1、推送通知
2、deep linking
3、需要暴露给React的原生UI控件
大约有80%的代码都是用JavaScript写的,可以在iOS和Android上通用。
HOT RELOADING
Hot Reloading在概念上类似于Android上的Instant Run。每当保存一个源码文件的时候,运行app的设备立即部署这些变化,因此加快了反馈。虽然它工作起来好于 Instant Run,但是仍然时不时的出现问题,需要重启app。
第三方库
我们不能否认很多时候我们需要解决一个别人在我们之前已经解决的问题,所以我们决定使用第三方库,避免重复造轮子。虽然在iOS和Android上有许多库可以选择,但是我们不敢对React Native说同样的话。当然肯定有相当数量的库,但是就跟我们预料的一样,他们中的一部分不能总是按照我们的预期工作。
发布周期
另一个值得一提的事情就是React Native的two week release cycle。虽然带来更多特性,让框架日趋成熟是好事,但是他们同时也带来了巨大的变化,也许这正是Facebook“快速行动,破除陈规”的文化使然。这些改变有时对于开发者来说是一个负担,因为在框架更新的时候我们需要花许多时间来修复。但是我们也不能否认这是预料之中的,因为框架还未到稳定状态,仍在开发之中。
代价的回报
虽然目前具有这些优缺点:工具的状态,文档的缺乏以及第三方库的不稳定,但是我们感觉相对于传统的原生开发,使用React Native确实能节省一些时间。根据我们采访过的开发者所述,在真实项目中,可以节省大约30%的开发时间。当然这只是比较高的一种估计,取决于各种因素,就如前面我们提到的,最关键的就是团队中有人具有web开发方面的知识。
为什么选择React Native
此时你可能觉得React Native只是另一个“一次编写,到处运行”的 框架,比如Titanium或者PhoneGap,但是你可能错了。就如Facebook在他们博客中明确声明的那样,他们阐述了和其它平台之间的不同,他们的目的是引进web上已经很成功的React模式到原生开发中,同时不管在什么平台都由一班人马开发。他们把这种方式称为“learn once,write everywhere”。
React Native的工作原理是把JavaScript文件嵌入到app中,并在本地运行它。你还可以把这些文件放在远程服务器上,在app联网的时候获取它们的最新版本。这可以让应用的更新非常快,无需在应用商店检查版本。也有一些第三方的库提供这样的解决方案,使用它们意味着对于数据不多的较小应用(比如节日app),后台可以不需要了。
绝大多数代码都是基于JavaScript和React的模式。因此典型的React Native应用团队应该是由JavaScript工程师组成的,因为理论上他们已经熟悉了此框架使用的工具和开发方式:React,EcmaScript,Redux 以及 Flex layout。
缺陷
文档
开始在一个像React Native这样的新平台上工作,我们所做的第一件事就是探索当前的文档,包括官方的和社区的。我们发现虽然Facebook努力保持更新,但当前的版本还是有相当一部分控件的文档匮乏。而这点在互联网上的文档中体现得就更明显了,因为几个新版本之后,这些文档通常都已经过时了。
CORE REACT NATIVE LIBRARY
当文档不能满足我们的时候我们尝试去看React Native的源码,但是我们对代码库的质量感到失望。可能是因为急于给框架增加新功能的原因,他们有时也许忽略了代码的简洁性。
说到核心的React Native library,我们发现许多主要的控件都是处于Work-In-Progress状态。在不同的版本之间,官方文档关于如何实现一些关键功能(如navigation)上不断的改变自己所推荐的控件。而要从一个控件迁移到另一个并不简单,需要做不少的工作。
第三方控件
当然是可以使用第三方控件的,但是在数量上无法和iOS和安卓相比。一个很大的问题在于,这些控件无法保证和React Native的新版本兼容。
原生SDK更新带来的问题
当iOS和安卓的SDK更新之后, React Native要过一段时间才能把这些饿新的API整合到自己的核心库中。React Native团队为了让开发者能够使用最新的API更新很快,但是优先级取决于每个API的需求大小。可能会出现下个版本引入某些新特性,而某些功能却遥遥无期。
总结
我们发现 React Native的一个很好的使用场景是那些临时性的项目,比如音乐会或者会议的app。
但是经过四个月的研究我们可以明确的说React Native还不是一个成熟稳定的平台。因此,我们认为React Native还没有准备好在长期的项目中被采用。这并不排除它可以用在其它类型的app上,以及团队中有级别较高的JavaScript专家的情况。React Native似乎更适合UI简单,动画不复杂,生命周期不长或者性能要求不高的app。
我们创建的demo app完全开源:https://github.com/novoda/spikes/tree/master/ReactNative/ReactTwitter。
关于更多的Novoda开源项目,请看http://novoda.github.io/。