这是一篇译文。原文在这儿~
当我第一次听说React Native
的时候,我认为它只是一种让web
开发者涉足原生手机app的方法。JavaScript
开发者可以用JavaScript
写一个iPhone应用,在我看来真是一件很酷的事情啊,但是我很快就对亲自使用它这个想法耸了耸肩。毕竟,我已经把原生iOS开发作为业余爱好好几年了,并且此时我已经为Chalk + Chisel专职工作几乎两年了。
我已经做了许许多多的app,我为这些app自豪。这些app在Xcode里使用Object-C语言制作,因为一直都是这样。这是苹果公司为我们写iOS应用所准备的,因此这就是我和其他开发者所使用的。然后当苹果公司两年前发布了Swift编程语言时,我毫不犹豫开始使用它。
仍然是在Xcode里面,仍然是苹果公司为了支持iOS应用开发而做的,因此我跳进去,把它。。嗯。。快速地捡起来。我对苹果的生态系统泡泡很满意。React Native
似乎就像是一个有趣的小实验,但是在我心里任何真正原生的app仍然需要用真正原生的方式书写。对我来说似乎有点浪费时间,不仅要学习JavaScript
(我没有经验),而且要用全新的方式构建应用,当我准备好以真正地方式开始构建它们的时候。
几个月之后,我有了足够的自信说我可能再也不会用Object-C或者Swift写iOS应用了。
我接到了一个新的手机应用项目,然后我检查了一下需求和设计。就在我将要点击那个漂亮的Xcode图标来新建工程的时候,我们的交互领导Adam走过来了,他说,让我们把这个做成React Native
吧。
他给我解释了我们这个项目的合同要求有一个清晰的途径让这个应用能同时被安卓使用。尽管React Native
目前还不支持安卓,我们清楚FaceBook正积极地干这件事。理论上,如果我们用React Native
来为iOS构造这个应用,那么当它发布的时候,它其中的许多部分都会适用于安卓。
好吧,我不高兴了。我感觉就像我刚刚站上iOS开发能力的顶峰,然后就被人要求把它们都扔掉。考虑到必然的学习曲线,我怀疑自己是否能够交付一个保证质量的产品。但是更重要的是,我怀疑React Native
自己是否有能力生产一个有质量的产品。回想起来,我甚至不认为这个怀疑是毫无根据的。那时候,React Native
仅仅发布了beta版。缺乏文档,关于React Native
的开源库和组件也很少。并且示例代码和Stack Overflow上的相关内容几乎没有。
我小心的尝试了一下。但是对我封闭的思想态度只是造成了更多伤害。我的第一个障碍是学习Flexbox
----React Native
中做UI布局的方式。我从interface builder那片大陆来到这里,要完全用代码写UI布局让我沮丧丧失了信念。哪怕最简单的视图我都要挣扎着去做。
但是不仅仅是UI----每一件事都是不同的。对我来说这是最大的争论点。
每当我被绊倒或者不理解一些东西,我就告诉我自己,用Object-C我5秒钟就能搞定了。每当我发现React Native
的一个bug时(有相当的数量。。。),我就会想,这个bug在Object-C里可是不存在啊,我为什么要坚持啊?
连续两周的时间我都痛苦地工作着。我从一开始感觉自己是个iOS开发专家,到另一种感觉自己这辈子一行代码都没写过。很挫败,知道一个周末我清空了自己的大脑。我回顾过去,意识到Adam对React Native
做了很多研究。我必须相信他作为一个交互领导不会把我带到沟里去。我发誓周一开始沉入工作,放低姿态,假装Object-C和Swift都不存在,解决这件事情。
。。。
学着爱上React
几周之前,我们提交了我们第一个React Native应用到苹果商店。对它的产生我极度自豪,我都等不及要写下一个了。在仅仅一个多月的时间里,我就完全上了React Native
的车。我是咋想的?
React范例
在React里,每一块儿UI都会存在于render()方法里,并且被“state”所控制。你的render()
方法定义了每一种状态的UI长什么样,并且只要调用setState()
,React就会指出什么需要改变,并且为你执行。想像一个简单包含一个“hello world”标签和一个按钮的视图。每次点击按钮,标签的文字都需要在“hello world”和“goodbye world”之间切换。在Object-C里,我需要在按钮处理方法里添加一些丑陋的if
表达式:
if ([label.text isEqualTo:@"hello world"]) {
label.text = @"goodbye world";
} else {
labe.text = @"hello world";
}
复制代码
这挺好。但是UI代码完全被从我第一次创建label
的地方(可以是代码或者IB)分离开了。在React里,我们可以在我们的状态里定义一个按钮点击布尔值。render()
里的labe看起来就像这样:
<Text>
{this.state.buttonClicked ? ‘Hello World’ : ‘Goodbye World’}
</Text>复制代码
我们的按钮处理方法很简单:
this.setState({buttonClicked: !this.state.buttonClicked});复制代码
所有的视图代码都在一个地方,状态控制一切。这让理解代码和排错更加简单了。
Flexbox
起初我非常讨厌的UI布局工具,现在变成了关于React Native
我最喜欢的东西之一。我承认开始时它挺难掌握的,但是一旦你做了,它会使得给各种各样不同的屏幕尺寸创建UI变得非常简单快捷。我曾经对Xcode的IB可视化布局非常上瘾。但是相比于Flexbox
,Autolayout
现在看来似乎过于复杂了。Flexbox
使用的CSS-esque
风格使得样式复用如同复制粘贴般简单。最重要的是,你可以在任何时候调整你的风格。
Live/Hot Reload
对了。看看你的按钮往右边移5个像素的效果就像 Command+S一样简单。React Native
可以被设定为在iPhone模拟器上自动重新渲染当前视图,而不需要重新编译Xcode工程。这很了不起,因为由于不需要重新编译你不仅省了时间,而且你可以在做一个被深深嵌套在应用里的视图时,不必每次都重新导航到那个视图来调整UI。
Android
还没出来,但是快了----那一定是惊艳的。我刚开始对React Native
犹豫不决是因为我已经喜欢上了iOS原生开发。我从不抱怨它。但是我也做原生安卓开发,体验不太好。React Native在安卓上很受欢迎,我正在倒计时等待它的到来。这将会给手机应用开发带来革命性变化,只需要写一份代码就能部署到两个平台上去。
更新:截止这篇文章发布,React Native安卓支持已经发布了。。。
回顾
我仍然怀念Xcode,或者说是一个IDE。我致力于一个相当好的React Native
开发设置,但是并不容易。Sublime Text,然后装了一堆插件,我得到了不错的语法高亮和检查。Sublime能够基于同一个文件中的变量和其他东西自动补全代码。但是缺少像Xcode代码自动补全的那种健壮性。我得始终把React Native
文档放在上面作为参考。
像输入React.PropTypes.f
这样的小事情,IDE不会告诉我是找“func
”还是找“function
”,这很讨厌。我还怀念Xcode的版本编辑器----它允许我并排地比较一个文件和之前提交的版本,甚至以行为单位撤销特定的修改。我发现一个第三方程序能帮我完成这些,但是对IDE来说最大的事情就是能一站式提供所有功能。
为了运行React Native
工程,我需要打开终端开启npm
包装,Chrome来排错,Sublime来编辑代码,最后用Xcode运行工程,开启模拟器。对这个壮观的体系来说,这只是一些小小的抱怨,但是对我来说这样的React Native
仍然不太好。我非常希望FaceBook的IDE----Nuclide将来能够减轻一些或者所有的不利因素。
Bridging
FaceBook没有也不会把iOS的每一个API开放到React Native
里,因此,为了那些缺失的部分,他们提供了一种“桥接”到JavaScript
。再一次,我走进React Native
,这里的文档真是很差劲。每当我发现需要桥接一些东西,我就想完全放弃React Native
,因为那些东西很自然已经在Object-C里了。但是一旦他们解释桥接过程的细节,并且提供好的例子,就不会那么吓人了。这仍然很麻烦,但是最终我能够看到每一个能够想象到的桥接都开源了,能够用npm使用。实际上大多数iOS的API已经可以了。
Bugs, Documentation, Open Source Community
如果我是从今天开始学的React Native,那么大多数(如果不是全部)最初的抱怨都不会存在。bug每天都会修复,新版本大概每周都会发布。文档还需要晚上,但是已经有极大改善。Facebook和开源社区对于这个框架十分认真。看到大家在Github和Stack Overflow上积极地参与提关于React Native的问题,这很棒。如果你是一个正在考虑使用React Native的iOS开发者,你要知道你并不孤单。React Native是令人惊叹的,你应该用开放的心态试着拥抱它。不要想我一样把自己格式化在熟悉的区域。
走出自己的舒适区,你可能发现比以前更精彩的东西。