React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。
这个项目本身也越滚越大,从最早的UI引擎变成了一整套前后端通吃的 Web App 解决方案。衍生的 React Native 项目,目标更是宏伟,希望用写 Web App 的方式去写 Native App。
React Native 一经推出,就获得众多开发者的关注。React Native 使得 JavaScript 能够开发真正的 APP, 它不仅有着与原生应用相媲美的体验,同时拥有着 Web 应用的优势和开发效率。React Native 鲜明的特点就是组件化,一个应用都是多个组件构成;同时为了更高的效率,React Native 采用了内存 Dom tree Diff 计算,优化了 view 的渲染效率和体验。使用 JavaScript 开发跨终端的应用是未来的趋势。
那么,现在使用 React Native 开发能给开发者带去哪些便利,又会遇到哪些坑呢,又该在什么场景选择 React Native 呢?这篇文章整理了一些我们高手问答栏目中的相关问答内容以解决大家的疑惑。欢迎各位一起讨论、交流、学习。
一、React Native 相关特性——首先来了解一下 React Native 的一些特性
React-Native是在React的基础上设计的(也许描述得不对),对于前端来说,纯业务组建(不涉及UI,仅仅是逻辑)能否在iOS,Android,Web上共享?从官方的视频看到,React Native提倡的是 Learn once, Write anywhere,这不是是预示着多个平台还得每个写一遍,不知道共享度能有多少?
你说的很对,React-Native是React基础上设计的,这是当时Facebook两个团队做的事情,ReactJS先出来的。如果是语法层面,不设计UI,是可以共享的。
React-Native请问是基于什么设计模式开发的?
设计模式硬套倒也想不出,基本3个层面:(1)语言层面:JS & JSX,这个对前端人员比较熟悉。(2)核心层面:使用Javascript内核引擎 + OC原生组件 (3)使用组件开发APP,就像搭积木一样。
Dom tree Diff 是什么? 具体是怎么运算的呢? 尤其是提高效率上。
举个栗子:以前我们需要给一个评论点赞,需要更新该评论下的赞,赞的用户昵称信息,我们暂且叫做视图重渲染吧,比如使用jquery, $('#container').empty().....render()。那么react做了一件什么事呢?react构建的是虚拟的dom,通过内部属性的改变通知虚拟dom进行内存计算(与旧属性的虚拟dom进行一次比较,即diff),将计算后的结果直接更新在界面上,不要我们手动管理视图。内存换效率。具体的可以看下这篇文章https://facebook.github.io/react/docs/glossary.html
既然原生上面有一层虚拟DOM,那按道理应该可以做到根据一套JS在不同的环境下渲染不同的原生代码,实现1次编写处处运行。而且Native是需要编译的吧,那它应该做不到H5那种的实时更新。还有一点,这层虚拟DOM能做到一套View同时渲染Web和Native两套界面吗?
是这样的,因为iOS和Android有各自不同风格的控件,有的区别很大,所以React-Native提供了Platform可以判断当前系统是Android还是iOS,然后渲染什么样的UI,这些可以写在一套js代码里,热更新不需要编译,React-Native有一个bundle命令,打包出来的bundle文件是可以直接被加载的,不需要编译。 如果想一套View渲染Web和App的话,UI部分的代码是不一样的,这个可以看React的文档和React-Native的文档,render渲染的JSX部分代码不一样。
既然Web的view和Native的view无法公用,那在Web上弄一层shadow-dom有什么意义?仅仅为了实现diff算法吗?React确实我没深入了解过,写NG比较多,感觉写React很繁琐
虚拟DOM主要是解决Web的一个性能瓶颈问题,类似cordova之类的跨平台解决方案性能瓶颈就在DOM上,虚拟DOM就是当DOM有更改的时候在进行DOM渲染,可以有效地减少DOM渲染次数,解决这个性能问题。NG更适合单页的web app或者说H5在native部分。
问下两个问题 1).React Native当初宣传的时候说的是 一次学习,处处编写。为什么React Native不是那种传统的一次编写,处处运行。 2)Native和Web端的React有联系吗?
React-native是从React发展而来的,最大的优势就是既有Web的热更新优势,又有接近Native的性能,核心思想是虚拟DOM,所以针对不同的平台编写不同的JS,实际上底层调用的还是原生控件,所以是一次学习处处编写而不是一次编写处处运行。 Native和Web端的react是有联系的。
React Native 组件的属性和方法够多够灵活吗?
目前React-Native的第三方库还不是很丰富,需要oc的支持和暴露,当然这只是目前。组件的方法不是很多,但是很好的处理了一个UI组件的渲染生命周期,足以控制组件;组件可以自定义和扩展,所以属性是可以灵活使用。具体的可以关注3个比较重要的属性:props、state、ref
二、入门相关——接下来,看一看 React Native 的相关学习资料
React Native学习成本如何,如何快速使用?
学习成本不算太高,我之前从来没做过Web开发,没接触过JS,也能入个手写一写,参考这篇小博文,入手会比较快:http://richard-cao.github.io/
入门学习也可以参考: https://github.com/xujinyang/react-native-android-guide https://github.com/jondot/awesome-react-native https://github.com/ele828/react-native-guide
相关入门资料推荐
干货:https://github.com/xujinyang/react-native-android-guide
https://github.com/LeoMobileDeveloper/ReactNativeMaterials
Redux的资料: https://github.com/xgrommx/awesome-redux
这个需要什么基础?还有就是以后的发展您是怎么看的?会代替原生还是和原生相辅相成?
(1)基础:前端基础,例如:JS、JSX、Flexbox以及熟悉iOS的组件即可。
(2)前景:现在最大的优势就是热更新;对于需要及时更新的部分,可以采用React-Native
(3)目前:相辅相成;未来的话,我希望更多是大部分替代原生。
用React Native 开发APP需要掌握其他哪些技能,除了React Native部分
会一些JS是最好的,掌握一些ES6语法之类的。
三、适用场景相关——技术总是脱离不了使用场景的
RN目前在项目实践中已知的坑有哪些?假如新开发一个项目,完全使用RN是否可行?另外想了解一下您在项目中使用的程度和场景,谢谢!
不太建议完全使用RN,因为Facebook也在不断填坑,每个月都有新版本,一个长期项目经不起频繁换依赖库的版本;我们公司也只是作为业余研究性质,不过RN的热更新思路真心不错,可以随时更换功能模块。需要注意的是,热更新和在线更新是不一样的,分别对应的是 hot-reloading 和 reload,调试时是通过 hot 选项控制;鉴于 hot-reloading 需要和服务器实时保持一个socket长连接和既有的不确定性,我不相信会有公司会采用 hot-reloading 的方案,应用于生产环境。如果真的应用hot-reloading了,那就分享下心得呗。
目前使用React-Native有那些局限,React-Native更适合开发那些应用?
React-Native还是有些坑需要踩的,现在Github上也能看到Recat-Native源码库都有不少开发者在提bug,更新的也很快。目前React-Native做一些内部APP还是可以的;目前对动画的支持不是很高,这个可以在一些APP中做一些优雅降级;更适合开发那些动画效果要求不是忒高、组件功能要求相对较少(如果团队中有OC的开发者可以忽略)的APP。很多坑,我们团队现在都在踩。
请问React-Native的目前推广和应用局限性有哪些?
React-Native技术的推广可以从公司内存APP试水;边踩坑边开发,React-Native的局限性除了平台因素,就是对开发者要求较高。当然开发效率来说,应该是很快的。如果团队中有Object-C成员,相对而言,上手就会轻松很多。
现在互联网公司开发一个新的移动APP,是不是建议使用React-Native
不一定,React-Native是可以减少一些开发成本,但是目前React-Native Android还有很多不完善的地方,目前比较适合做偏UI方面相对简单的一些需求和功能 。
四、React Native 与其他开发工具、方式对比
想知道,这个与 Phonegap 的比较,包括开发效率,学习曲线,用户体验,工具的完善程度等。
Phonegap 和 React-Native 还是不同。React-Native 内部在 iOS7 版本以上采用的是JS Core Engine 解析的,在版本上是降级使用 WebView。React-Native 针对前端开发者上手难度应该不是很大,主要熟悉Flexbox布局、JSX语法、React-Native API。
这个同跨平台开源的.NET + C#开发通吃平台的APP相比,差距在哪里呢?
你说的应该是指Xamarin吧,这个我有尝鲜过,收费的商业解决方案,我感觉是主要依赖官方提供的控件和库,React-Native相对学习成本没那么高,毕竟现在做C#的相对小众,React-Native没提供的原生控件你可以通过它提供的扩展来自行扩展,开源而且社区相当活跃,我认为前景很广阔,个人认为要比Xamarin好,性能方面没对比过,因为我没买Xamarin的方案。
能从学习周期、开发难度、运行速度方面分析下,AngularJS和React Native的差异吗?
对我个人来说,我是一个Android开发者,之前没接触过Web和JS,Angular我也有看过,Angular学习成本我认为比React高,做APP方面的就是ionic,React是个纯UI的东西,React-Native也是,然后提供了和原生APP的扩展模块,开发周期我感觉对于我来说肯定是React比较快,运行速度方面React-Native是要胜于ionic的。
React-Native开发出来的APP和原生的APP的性能有区别吗,React Native做出来的安卓APP是不是没有原生的流畅啊?
React-Native开发效率高于Native;React-Native效率和体验高于Hybird;React-Native整体性能跟Native差距不大。Facebook给出的性能测试是接近原生的性能,如果不是很复杂的APP,看不出什么差别,但是如果相对复杂的动画UI之类的,那肯定还是原生更胜一筹。不过如果只是开发一个功能性APP的话基本没啥大差别了,毕竟现在的Android手机性能也很好。
用这个你觉得在与我们这帮原生Android App工程师的竞争中,你们最大的技术优势是什么,对比原生,你们的劣势有在何处?
最大的技术优势:iOS和Android可以一定程度上的代码公用,减少开发成本和开发周期,可以随时线上热更新。 和原生相比的劣势:目前React-Native Android不适合做相对复杂的动画效果和UI,体验上会有一些问题,而且热更新只是针对纯React的模块,和原生交互的会有原生代码,热更新就不好用了。目前我感觉最好的方式还是原生+React的混合开发,根据需求做技术选型。
我们目前在用国内的APICloud来做移动端的开发!我感觉React-Native这个东西相应该没有APICloud方便吧!还有React-Native和Phonegap应该差不多的吧?
React-Native和Phonegap差很多,React-Native性能接近Native的性能是因为React核心是虚拟DOM,通过diff算法来进行有效的DOM更新,从而突破Web的DOM性能瓶颈。Phonegap,也就是现在的开源方案cordova,它做出来是Hybrid,RN做出来是Native,性能是最大差别,不过如果你的是资讯类应用,不计较性能,团队又多Web开发人员也不妨考虑cordova。还有你说的APICloud,实际上是给原生APP套了个WebView壳,尤其在Android上会有性能问题。
我感觉最好的方式还是原生开发,虽然需要的精力多了些但最终是值的,你说呢?
这个就看产品和需求怎么定了,技术选型往往都是跟着产品和需求跑,毕竟技术是服务用户的嘛,我觉得互惠互利吧。
另外Swift开源后,将来有可能第三方机构开发出Siwft可以同时构建iOS APP的平台,所以我感觉还是学好Java和Swift比较好一些,混合开发也许以后会好一点,但目前很长一段时间和原生开发还是要差不少吧。
你要说的是Swift同时构建Android APP吧?不排除这种可能,不过目前混合开发还是比较主流的,毕竟BAT和其他一线二线互联网公司都在用,Web和原生结合可以解决很多产品需求上的问题。
相比其他移动开发,它的优势是什么?
RN的优势在于性能与灵活性的平衡,比Hybrid好的性能,热更新有比Native好的灵活性。快速做出业务逻辑和UI 基本一致 、性能介于原生和混合的APP。
五、入坑之后,就要不断的填坑——看看各位使用React Native 时遇到的问题
React-Native 和 React 的代码可以复用吗?
目前我们团队也在做这件事,想要完全的复用还是很难的。需要做就是将一个方向打通,比如React转Native。那么就会遇到如需要将div、img等封装成React-Native的View、Image组件;同时css样式的改变和css-layout的打通也是比较耗时的工作。后期,我会在大会上分享我们团队正在做的这件事。
还有就是动画这块,因为原生的有很多框架,甚至可以用opengl,那React-Native有望做到吗?你说的执行的是打包完成的JS文件。那提交到Appstore以后,怎么来热跟新?覆盖掉以前的JS文件吗?苹果现在支持应用可以这样了吗?
你把JS Bundle文件改成线上拉即可。因为React-native本身就存在OC的代码,审核是可以通过的。React-Native提供了transform;当然比如页面的切换的动画也是支持的;同时有些效果可以在Webview中使用Canvas。
请教一下,在开发模式下能否将转换的JS直接打包到APK中而不用Reload,另外可以说说你对访问外网JS的想法吗?
直接将JS打包不用reload是可以的,但是开发模式下这么做会比较麻烦。访问外网JS我感觉可能会有一些安全性方面问题,其他的还好
我在学习React-Native,现在要用post或者get请求和服务器进行交互,怎么做?有没有一些demo?
查看官方文档:https://facebook.github.io/react-native/docs/network.html#content,讲的很清楚了,用法比较简单
最近在学习React Native,开发过程中难免会涉及到与原生页面进行调用和传值。请问如何实现。是否有开源demo参考?
https://facebook.github.io/react-native/docs/native-modules-android.html#content 请参考这个,还是不难的,我做的这个小模块就用到了
看了OC-JS的通讯原理,发现是他们之间的通讯是单向的,只能OC调用JS。那事件是如何转化的呢?比如:在JS中使用window.setTimeout()设置定时触发事件,那这个事件是转化成OC的定时触发事件,然后等待OC来执行吗?
React-Native中内置了JS引擎;低版本系统降级的是采用Webview。
是啊。但是既然是调用原生控件,那这个控件就是在OC层绘制出来的,能绑定的事件是不是应该也只有OC的事件?像一点点击事件之类的,是在OC层触发,还是在JS层触发呢? 在iOS7以上版本,先不考虑使用WebView的情况。
嗯嗯,iOS7以上可以尝试React-Native
对于RN我一直很担心就是国内的一些第三方服务的支持情况?如果都需要iOS和Android对于它们官方的SDK进行封装的话工作量就太大了?你们是否使用了相关的服务:比如支付、登录等。
对于微信、QQ、支付宝等都已经有开源封装,随着RN的推进,以后会有更多第三方服务的封装,我们用过微信和支付宝的,推荐一下:https://github.com/reactnativecn/react-native-wxhttps://github.com/huangzuizui/rn-alipay
我在华为6P上构建各种红屏,开avd各种正常,这是什么原因?
红屏是因为bundle问题吧,如果是debug状态,你要监听电脑本地的node server8081端口,来reload js代码;如果是release的话,要先用react-native bundle命令打出bundle,然后一起打包成apk
Android机上使用React Native占用内存情况如何?有出现内存溢出的可能么?你用的是模拟器,还是真实Android系统?Android 5.0?
我在我的测试机上没出现过内存溢出哈,不过我做的功能也不难,其实内存溢出这个事情原生代码写的不好也会出的吧。都是真机,有5.0的,也有4.x的,4.1以上
前段时间接触过React-Native,当时发现Android好多Widgets都没有哎,是我使用的方式不对吗?
还有React-Native目前只能加速APP build 的速度吗?我看源码只有dev的时候才会加载网络端的bundle,这样感觉意义不大啊,我尝试修改其源码使release版也可以加载在线bundle,不过后来没时间就放弃了。
Android常用的控件基本都有了,其他的如果自己有需要也可以自己实现,这个在 React-Native 的官方文档有提到 Native 模块和 UI 模块与 React 的结合部分。 React-Native在Release下也可以加载在线的bundle,可以参考博客:http://richard-cao.github.io/。react和加速app build的速度没必然联系。
最终发布的安装文件不会有被反编译或者被查看到JavaScript代码的风险吧?(毕竟是用Javascript开发的)。另外,你们踩坑之路,遇到难题后一般去哪里查文档的? 有没有优秀的RN文档资源或者图书推荐?
不用担心,Facebook打包出来的js代码是经过混淆的,反混淆出来也难以看出业务逻辑。
一些学习资料:https://github.com/jondot/awesome-react-native https://github.com/ele828/react-native-guide
原生Android开发获取本地APP图标都是Drawable类型的,如何把本地APP的图标显示在RN的Image上?
http://reactnative.cn/docs/0.31/images.html#content 使用混合App的图片资源,如果你在编写一个混合App (通过Xcode的asset类目或者Android的drawable文件夹打包)
React-Native ListView上1000条数据如何?卡不卡?很多非原生前端(包括很多原生前端)并不晓得React-Native的性能如何,更可能是压根不知晓其性能消耗情况。React-Native真的如其吹嘘的具备原生的体验吗?
你说的是这个issue吧?https://github.com/facebook/react-native/issues/499 新的版本已经修复了;附带一个三方的解决方案 https://github.com/sghiassy/react-native-sglistview
这个也算fixed?react-native-sglistview也算是解决方案?看看他的issues https://github.com/sghiassy/react-native-sglistview/issues 还有多少坑。
谢谢你的热心说明,我对ListView的性能研究得不够深入,总结来说RN还真不适合做大量数据列表
最近在调研RN,主要面临两个问题,1是可复用的ListView,2是好用的tabbar,还请推荐下,有没现成的组件,如没有,自己写可不可行?不知iOS方面有没有兼容的计划?
ListView解决方案,https://my.oschina.net/droidwolf/blog/750479
iOS方面,http://blog.wix.engineering/2016/06/30/recycling-rows-for-high-performance-react-native-list-views/
请问RN在项目版本管理中,如何分配目录方便团队共同使用?包括新加入成员。
RN还是比较好做版本管理的,项目规模2到4个人,其中一个主程,按功能模块分工,遇到冲突由主程协调其他开发协调解决,不过冲突基本很小,没有二进制文件的冲突也比较好解决。
之前想学习RN Android开发,Windows下搭建开发环境各种坑,最终放弃。不知道现在RN Android针对Windows环境有没有改进?
不好意思,我也没试过Windows下的体验,估计进展不大吧,因为Facebook是技术主导型公司,比较少用Windows吧
国内搭建环境都极不顺利,有什么好的方法吗?
npm挂一个淘宝镜像的代理,可能会快一些,不过最好还是有科学上网环境, 淘宝npm镜像:https://npm.taobao.org/
六、也有不少开发者对增量更新这方面比较关心——有关增量更新的问题
React-Native实现的应用能否实现增量更新?如果能,苹果商店会限制此类应用吗?
可以实现增量更新;大家都知道天猫已经上了一个活动页,至少目前来看,Apple是不会限制的。相信大公司应该有大公司的胸怀。
React Native 应该是支持热跟新吧,就是通过服务端来控制界面,这样就不要老提交苹果审核了,但是我不确定支持吗?还有就是他和原生开发有什么区别?原生能做的它都可以吗?
远程的热更新是ok的,因为执行的是Jsbundle,Jsbundle是打包完成的js文件;原生做的它都可以么?--至少可以通过各种途径去实现,React-Native iOS版本目前也是公测中。