知乎上关于ReactNative的评论汇总(网友们有才哟...)
Posted zhangjiaofa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了知乎上关于ReactNative的评论汇总(网友们有才哟...)相关的知识,希望对你有一定的参考价值。
React native充分利用了Facebook的现有轮子,是一个很优秀的集成作品,并且我相信这个团队对前端的了解很深刻,否则不可能让Native code「退居二线」。
对应到前端开发,整个系统结构是这样:
JSX vs html
CSS-layout vs css
ECMAScript 6 vs ECMAScript 5
React native View vs DOM
无需编译,我在第一次编译了ipa装好以后,就再也没更新过app,只要更新云端的js代码,reload一下,整个界面就全变了。
多数布局代码都是JSX,所有Native组件都是标签化的,这对于前端程序员来说,降低了不少学习成本,也大大减少了代码量。不信你可以看看JSX编译后的代码。
复用React系统,也减少了一定学习和开发成本,更重要的是利用了React里面的分层和diff机制。js层传给Native层的是一个diff后的json,然后由Native将这个数据映射成真正的布局视图。
css-layout也是点睛之笔,前端可以继续用熟悉的类css方式来编写布局,通过这个工具转换成constrain布局。
系统只有js-objc的单向调用,就是把原生UI组件的方法通过javascritcore或者webview(低版本ios)映射到js中来,整个调用过程是异步的,这样的设计令React native可以让js运行在桌面chrome中,通过websocket连接Native code和桌面chrome,极大地方便了调试。对其中的机制Bang的一篇文章写得很详细,我就不拾人牙慧了:React Native通信机制详解 « bang’s blog 。但这样设计也会带来一些问题,后面说。
点按操作也被抽象成了一组组件(TouchableXXX),这种抽象方式是我在之前做类似工作中没有想到的。facebook还列出Native为什么和web「手感」不同的原因:实时的点按反馈和取消能力。React Native 这套相应机制设计得很完善,能像Native code那样控制整个点按操作的所有过程。
Debug相当方便!修改了js以后,通过内建的nodejs watcher编译成bundle,在模拟器里面按cmd+r就可以看到效果。而且按cmd+d,可以打开一个chrome窗口,所有的js都移到了chrome里面运行,所以什么断点单步打调用栈,都不在话下。
上面的既是特点也是优点,下面说说缺点,或者应该说:「仍然遗留的问题」,在我看来,这个方案已经超越了Hybird方案。
系统仍然(不得不)依赖原生组件暴露出来的组件和方法。举两个例子,ScrollView这个组件,在Native层是有大量事件的,scrollViewWillBeginDragging, scrollViewWillEndDragging,scrollViewDidEndDragging等等,这些事件在现有的版本都没有暴露,基本上做不了组件联动效果。另外,这个版本中有大量组件是iOS only的:ActivityIndicatorIOS、DatePickerIOS、NavigatorIOS、PickerIOS、SliderIOS、SwitchIOS、TabBarIOS、AlertIOS、AppStateIOS、LinkingIOS、PushNotificationIOS、StatusBarIOS、VibrationIOS,反过来看,剩余的都是一些抽象程度极强的基本组件。这样,用户必须在不同的平台下写两套代码,而且所有能力仍然强烈依赖 React native 开发人员暴露的接口。
由于最外层是React,初次学习成本高,不像往常的Hybird方案,只要多学几个JS API就可以开始干活了。当然,React的确让后续开发变得简单了一些,这么一套外来的(基于iOS)、残缺不全的(css-layout)在React的包装下,的确显得不那么面目可憎了。
另外,React Native仍然很不完善。文档还不全,我基本上是看着他的示例代码完成的demo,集成到已有app的文档也是今天才出来。按照官方的说法,android版本要到半年后才发布:Blog | React ,届时整个系统设计可能还会有很大的变化。
PS,在使用Tabbar的时候,我惊喜的发现他们居然用了iconfont方案,我现在手头的项目中也有同样的实现,不过API怎么设计一直很头疼。结果,我发现他是这么写的:
更新于2月3日:关于我们的最新动态,我们把React跑在了其他Native的实现,让React在无线不仅是ReactNative,就像我之前说的React更是一种模式:
对React的理解,认为React是一种架构模式,无论是内建的DOM、Native还是React Canvas都是的一种基于React模式的具体实现,当我们评价React Native还是评价React Canvas,都是React生态想象空间的一种表现。
React提出重新思考UI开发过程,其实不是面向浏览器,而是所有的前端,因为对前端开发而言我们需要涉及的领域已经开始包括了Web与Native。
这里也分享淘宝基于React正在进行中的一些实践,是我认为能戳中极客们的G点让大家为了亢奋的事情。
React Web端
团队里最早使用React的线上产品: 知了,前端是React+KISSY, 后端是淘宝基于Node.js解决方案Midway,这是完全由前端主导的项目,在前端,通过React极大的方便了富交互页面的构建,同时也轻松的解决了页面内业务组件状态同步等问题。
淘宝懂我,我们在面向用户的创新业务里毫无悬念的引入了React,不是为了技术而技术,而是基于React的开发过程,促使大家一切都是以组件的思考模式,这的确让业务也变的更加清晰,开发效率提升,维护成本降低,发现React的确改变之前曾经非常困扰我们的事情。淘宝懂我的入口在“我的淘宝”里,大家可以去围观: 淘宝网 - 淘!我喜欢。
React Native端
F8大会当天,React Native终于正式开源了,这着实让人兴奋了一把,因为我们知道React Native即将成为在手机端上必不可少的开发模式之一。因为已经有React的开发经验,稍微过目下文档,很自然就能过渡到React Native的开发。笔者稍微努力了下,复刻了下手机淘宝的首页,不到个把小时我这个菜鸟就差不多完成了大体的样子,让人惊讶于React Native这套技术方案的生产力。
而且React Native开发与Web几乎一致的开发与调试体验,也更让我惊艳,这效率上差距可见一斑。
但是,Android版本还未开源,React Native只支持iOS7+平台,而在淘宝移动业务里依旧需要支持iOS6平台,所以在iOS6与Android平台上只能暂时继续跑H5页面,在技术上我们很快就确定将React Native代码转为H5版本,做到大家梦寐以求 Write once, run everywhere,就如大家在微博http://weibo.com/1797897057/CcFmN3nwp上看到的,我们就做了一个简单的DEMO,基本确定这个方向的可行性。
兴奋的同时,一个无法回避的事实,对Web前端来说这是一个全新的领域,就是一个大坑,需要我们去填平,填平这些坑的就是我们配套的基础设施。如图这是淘宝基于React的已经完成或正在进行中相关领域,当这些基础设施相对完善时,就是React Native爆发的时候,而我们现在做的事将是未来的肩膀。
结束语:Web是未来,Native是当下,而我们在未来与当下之间。
编辑于 2016-02-03 19 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
69
赞同反对,不会显示你的姓名
赵望野,《你不知道的 javascript》译者
time david、ds dsdd、李飞 等人赞同
先说结论:必有作为,但绝不会是一家独大,甚至很难成为主流。
用过 React 会知道,React 的核心概念是「DOM Representation」,在开发者和 DOM 中间构建一个中间件,然后通过高效的算法来 diff 两次 Virtual DOM 渲染的差异,然后在最小范围内更新 DOM,在大部分情况下——注意是大部分不是所有——这种做法都是足够高效的,但是对于精细的需求、动画控制等——比如在移动设备上做一个跟随 touchmove 的元素,还要各种 transition 等等——场景 React 会显得力不从心,或者很笨拙。
但是抛开这些太过复杂的需求,React 是有能力满足大部分的业务场景的。
再说 React Native,这几天不停看见媒体用「Web 开发要 XXX」一类的题目来发稿,真是吐槽无力。React Native 根本都不算 Web 开发好不好——Webview 都没了还 Web 个 bird 啊…
React Native 继承了 React 在 JavaScript 的扩展语法 JSX 中直接以声明式的方式来描述 UI 结构的机制,并实现了一个 CSS 的子集,这把「DOM Representation」的概念外扩成了「UI Representation」,由于不是操作真实 UI,就可以放到非 UI 线程来进行 render——所有做客户端 UI 开发的都应该知道 UI 线程是永远的痛,无论你怎么 render,render 的多低效,这些 render 都不会直接影响 UI,而要借由 React Native 来将改变更新回 UI 线程。
由于目前没有任何示例代码,也看不到更细节的实现机制介绍,所以以下部分为猜测。如果 React Native 沿袭 React 的机制,就会同样是把两次 render 的 diff 结果算出来,然后把 diff 结果传递回主线程,在最小范围内更新 UI。
所以,核心是以下三点:
1. 在非 UI 线程渲染 UI Representation
2. 高效的 diff 算法保证 UI update 的高效
3. 没错,由于中间件的机制,React 很有可能成为一个跨平台的统一 UI 解决方案,可以理解为 UI 开发的虚拟机?
声明式 UI 开发,简单快捷,必然大有作为。精细控制无力,复杂应用场景无法很好满足,必然受限。
最后再说一句…不是能写 JavaScript 就叫 Web 开发…
============================================
看了@Rix Tox 的答案后来补充。
这个答案作为补充或扩展来回答「React + Flux 模型」是非常好的,但问题是「React Native」。React Native 的亮点是解决了在 Native 中使用声明式来开发 UI 的渲染效率问题,而不是软件架构和工程模型的问题,无论是 iOS 还是 Android 固有的模型也是非常好的。为啥 FE 会在乎这个?因为 FE 最习惯用声明式来开发 UI,而这么多年想参与到 Native 开发中的目标都没能达成,就是受制于最终的运行效率。
React 作为一个 View Component 封装解决方案来讲,同 Polymer 以及 AngularJS 中 Directive 并没有本质区别,只是用不同的思路来封装 View 而已,用 React 也不一定非得用 Flux 模型,React 替换 Backbone.View 组件,用纯朴的 MVC 模型来描述也是 okay 的。但是当 component 很多且互相嵌套时,就需要有一个合理的模型来描述通信机制,优雅且高效,那就是 Flux 模型了。前年 React 刚发布,还没有提出 Flux 时,我们在终端产品中开始小范围尝试 React 就遇到了 component 之间通信麻烦或者不合理的问题,当时的解决方案是全局实例化了一个继承 Backbone Event 的对象作为 event hub,所有的 component 都在其上来 reg 和 trigger 事件。现在看来,就是简化版的 Flux 模型。
不过我确实有一点遗漏的内容,React 的 DOM Representation 或者 React Native 的 UI Representation 的每个 component 都有一个 state 用来描述状态,而 component 某种意义上来说就是一个状态机,因此渲染结果是幂等的。
近些年 Web 前端的开发越来越多的受到工程复杂度上升导致整体性能下降的困扰,所以最近几年的新型框架大多有一些独特的机制来提升性能,而这些机制大多是从 Native UI 或者游戏开发中借鉴来的,比如 AngularJS 中的数据 dirty check 机制,比如 React.js 中 Virtual DOM 的 diff 机制,这些特点同以前的前端框架或库相比,真的是非常特殊且先进的改进,往往也会成为这个框架或库的亮点之一,对 FE 来讲当然就是新鲜玩意啦。
最后,Facebook 在 php 中直接写 HTML Tag 那东西叫 XHP,对应是 JSX 扩展语法,和 React 关系也不大…
编辑于 2015-02-06 4 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
6
赞同反对,不会显示你的姓名
Vincent 4J
xiaogang、Jeremy Young、李喆 等人赞同
Facebook 在 React.js Conf 2015 大会上推出了基于 JavaScript 的开源框架 React Native,结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用。
下面是对 React Native 官方文档的完整中文翻译教程:Facebook React Native 中文教程
发布于 2015-04-25 添加评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
5
赞同反对,不会显示你的姓名
宋阳,各种心理扭曲的问题,乌烟瘴气
yangxq、钱宇翔、xrush 等人赞同
其实最应该期待的是ui以及编译环境的整合,这些已经有ionic做榜样,js to native也有Ti趟了几年雷。工程结构上比ionic的angular讨巧。
看起来会牛的,但这些优势目前我串不起来,没法预期会是个什么东西。
我多说一点,以我的观察,没ide火起来难。
编辑于 2015-01-29 添加评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
258
赞同反对,不会显示你的姓名
rank,公众号「跨界码农」
奶牛、张jack、Nemo 等人赞同
凑个热闹,正好最近在玩这方面的技术,来个技术贴。
注:在没有同意的情况下,禁止转载。
WebView 里无法获得的能力虽然是「体验增强」与「端基本能力」,但现都基本上有成熟解决方法。但后期的 UI 和 Layout 的性能反而是目前 Web 技术欠缺的。所以,无论是 Titanium 与 React Native 都是解决性能作为探索的出发点。
一、性能慢与快的分水领.
慢与快的标准,是按照每秒大于等于 60 FPS(60 帧每秒) 的理论,而为什么是 60 FPS,这不多描述。
按此理论,那么「每帧」里所有的操作都必须在 16ms 完成。
二、WebView 里 UI 性能慢的原因.
WebView 单线程模型;
DOM/CSS 排版复杂,在渲染上需要大量计算;
动画是也很重要的考量因素。
多说两句动画。
最早做动画都是用 setTimeout/setInterval。
而 setTimeout/setInterval 的处理回调的时间 tick time 精度都在 16ms 左右。
所以,可以想象正常用这两个函数就已经 16 ms了,再加 reflow/repaint/compositing 卡顿或跳帧就是家常便饭了。
还好的是 w3c 标准和各浏览器厂商较早就支持了动画接口 RAF(RequestAnimationFrame 函数)来处理动画帧回调。解决了上述 setTimeout/setInterval Animation 不足的问题。
三、DOM 性能低下的原因.
浏览器执行的几个步骤:
restyle/reflow/repaint 触发条件:
了解完以上信息,考虑以下条件:
把 JavaScript 逻辑、复杂的 DOM 与样式合成,并完成渲染;
HTTP 请求下载多媒体;
在一个线程里;
移动上的 ARM 架构;
以上操作能在每帧 16ms 里完成,想想都觉得是一件 TMD「不可思议」的事情。
于是各种各样的奇葩优化出现了。
四、WebView 里高性能组件分类.
已知的高性能组件的几类方法:
1)常规方法.
这类的原理主要是利用人为或规范的方式,减少 restyle/reflow/repaint 触发次数:
通用组件优化 DOM 结构,甚至用 Virtual DOM(虚拟 DOM)减少 reflow 和 DOM 的复杂度;
优化 CSS,少用或跳过 repaint 阶段。用编译的手段识别部分 CSS,将 left/top 变换变成 transform;
跳过 layout 与 paint 阶段,就是多使用 Layer composite 技术,即 css 的「opacity」和「transform」属性作动画。
只能在 css 和 DOM 结构上去抠出些性能优化的空间,缺陷优化空间有限;这种优化技巧通常是放在最后调优时冲剌使用,不能做为常规手段。
2)进阶方法.
原理是尽可能利用 native 能力,甚至将 JavaScript 转换成 native App 代码。
用 JavaScript 调起 native 组件,将增强与高性能组件交给 native 来处理,以前在 FEX 提的「轻组件」就是这么做的。这个原理类似 PC 时代的 ActiveX;
将 WebView 里无法实现的功能用 native 实现。
利用 native Activity 的渲染线程,分担浏览器渲染压力(WebViewCoreThread 是 WebView 线程)。
最 dirty 的事在于处理 native 上 UI 的层次管理。
需要后台有线程一直在检测 scroll/resize/ui change 时 UI 边界是否有相互覆盖与叠加的问题。
JavaScript 翻译成 Java/OC 代码。类似 React Native/Titanium,将 JavaScript 翻译成 native 代码,特别是 UI 组件上。(有兴趣的同学可以反编译 React Native 写的 Facebook Group)
例:用 React,通过虚拟 Web UI 映射至 Native View,并且将代码逻辑翻译成 native。
3)新方法 — Canvas UI.
这也是要说的重点,用「开发游戏」的思路来做 UI 组件探索,我把它称为 Canvas UI framework。
五、Canvas UI framework.
用游戏的思路做 UI,最早我有这个想法是 2014 年。
1)为什么要用 Canvas?
Canvas 是 H5 的画布元素,即一个 DOM 元素。通过脚本控制逻辑给画布上增加文字与图像,而浏览器只需要绘制一次形成一幅图。
只用一个 Canvas DOM 元素,降低 DOM 数量与渲染的复杂度,可以将原来 CPU 密集型变成 GPU 操作。
绝大多数针对 Canvas 是用硬件 GPU 加速渲染。
GPU 的 ALU(计算单元) 比 CPU 要多很多;
而控制运算(逻辑)则可以用 JavaScript 在 CPU 里做,甚至还可以用 WebWorker 多线程处理 CPU 密集型的操作;
从而达到充分利用硬件资源的能力。
Canvas 画布无论是 JavaScript & H5,还是 native 都有类似的 API。所以:
本地调试可在浏览器里完成。
最差方案可以用 Canvas UI 跑在浏览器里。
更进一步,可以把浏览器 Canvas 接口的反射到用 native 画布上,以此提高性能。
值得一提的是,腾迅的 X5 内核已经将 egret(白鹭游戏引擎)与cocos2dx内置,
所以时间线拉长来看,WebView 的画布功能将会更加强大。
在 2014 年中时,很多人见识过默认置入 cocos2dx 引擎的浏览器,用 WebView 玩「捕鱼达人」很流畅。
由此说明 Canvas 做 UI 组件可行性还是蛮高的。
2)解决方案.
用游戏的思路来解决 DOM paint 的问题,业界早就有实验。
最早实验的是 zynga 做 angry birds 游戏的厂家,2010 年写的 demo scroller:
zynga/scroller · GitHub
Scroller - Canvas
设计、开发一个基于 Canvas 的 UI 框架系统,由于系统相对比较复杂,需接管浏览器构建的整个过程:
验证在实践环境中的效果,要把原来页面的 DOM 写成 canvas,再加上一些调优与比较,工作量相对大,(包括 zynga 也只是实现了一个简单的 demo 而已)
就暂时搁置了。
最近这阵子在翻 github 与新闻时,我惊喜的发现也有人在做同样的事了,最后发现 Flipboard 同学们写的一个 demo:Flipboard
这个 demo 足够复杂,动画也足够多、炫。是用 canvas 来构建整个 UI。
测试过后:
这么复杂的 demo 在 MI4 以及配置以上性能很好,流畅度无限接近于 native,比较理想。
对比过 G+ 的 Android 应用,G+ 的 App 从动画上比 Flipboard 提供的的 demo 还「卡」些。
在小米 Note 上的动画流畅度已秒掉 iPhone 6,非常赞。
按照摩尔定律,可以预计明年 Note 的标配的 CPU 和 GPU 配置会成为主流。
而现在用 canvas UI 框架用在 MI4 以下机器仍然比较慢。而 2015 年 H5 开发 App,对很多公司来说只是 plan B 计划,大公司甚至 plan B 都不是。所以,如果一定要在纯 H5 上搞牛逼动画,还是再等等吧。
3)布局系统 css layout.
说回到 Canvas Component framework,回到我上面画的这张图:
UI 组件基于「文本」与「图像」。但 framework,除了 UI 组件本身以外,还需要有 Layout,而 css 只适用于浏览器本身的 layout 而无法适用于 Canvas 画布。
要给开发者好且排版可控的方案,那就要开发一个用 JavaScript 实现类似 CSS 的布局子集的框架。
否则 UI 的组件在画布上没有 layout 就无意义。
这个布局框架实现成本(简单实现)理论上并不大,大的是在于未来增加新 Feature 并相互组合时与浏览器本身有差异,需要有完整的 unit test。
正好最近 facebook 也开源了一个用 JavaScript 写 css layout 子集的解决方案,实现了:
padding
width
margin
border
flex
position( relative/absolute )
等等。
github 地址:facebook/css-layout · GitHub
这些 css 布局子集基本能满足我们前期开发预期。
4)开发框架.
用 css-layout 再加上 UI 管理层,就可以比较清晰的实现出 canvas 的 UI 组件框架了。
那么,剩下的事就是:
应用开发框架的选择,如:选择 React/MVC 框架。
模拟 DOM 层次,即图层管理。
并且,让我非常欣喜的是,Flipboard 在 2 月已经完成了构建,基于 React 框架。
https://github.com/Flipboard/react-canvas
基于 css-layout + React 基础上整合而成。
六、Canvas UI 框架不足与风险.
看上去 Canvas 框架这么牛逼,但有很多缺陷。
对开发人员的要求较高。需要用 JavaScript 实现一些浏览器基本的布局、图层管理。
第三方使用者学习成本高。不象是用传统「标签」就可以实现 UI 在浏览器的输出。
开发者是否买账,对于框架的开发易用性有「很大」的挑战。
对开发质量提出新要求。
由于所有的 UI 组件与交互都在画布 Canvas 里,所以调试成本比较高,需要有较为完整的 Logging 与 Debugging 方案。
用户可用性会受影响。例如:
语音无法识别 Canvas 里的文字。
无法象 WebView 里一样将画布里的文字选中并复制出来。
总结.
Canvas UI 作为柳暗花明又一村的技术产品,https://github.com/Flipboard/react-canvas 短短一周多,已经近 4K 的 star。确实很赞。
现在看 FB 开源 react native,不如好好研究 react-canvas 。
原文来自:http://mp.weixin.qq.com/s?__biz=MzA5NDY0ODkxNA==&mid=202786512&idx=1&sn=c3b470b68a6d73953d38c309ea2f5f4b#rd
编辑于 2015-02-28 25 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
169
赞同反对,不会显示你的姓名
Rix Tox,太不專業了
zhiquan-yu、bitecode、周怒 等人赞同
======= React Native 正式发布 =======
官网:React Native
没有参会的我只能等这一天了。虽然慢了点,但还是讲讲第一体验吧。
首先一点,React Native真的是完完整整地将React.js的特性搬到了iOS平台上。所以我最开始说的关于数据流的控制以及Diff Update这些作用在React Native也能得到很好的体现,所以我前面说的竟然没有跑题。
不过,尽管都是用JavaScript,但是用React做iOS开发跟做网页开发是完全两种体验。在React Native里你见不到
,但是会经常用到,也就是说我们已经完全脱离了HTML的框框,而是用标记语言的格式写类似XML风格的JS代码,调用的都是iOS平台下的原生组件。App在运行时也不会去跑一个WebView,而是只运行一个JavaScript Core VM,然后用Objective-C搭建一个Bridge把iOS的各种组件Expose给JS代码。React Native实现了一些常用的组件的Bridge可以直接在JS中使用,如果开发者需要使用其他的组件可以自己写一个Bridge将API Expose给JS VM,所以理论上Native App能做的事情React Native都能做到。React Native将Flexbox排版移植到了iOS上,也就是说开发者可以不再忍受Constraint-based的Layout Engine,而转而使用更直观、更像CSS的Boxed Layout。
JS VM跟iOS的渲染是处于两个线程的,也就是说JS代码控制逻辑和Viewer,iOS Framework对Viewer进行渲染。从效率上来看由于JS跟O-C处在两个线程,不会出现因使用VM而带来的卡顿,相反App的使用体验十分流畅。对此不太确信的可以尝试一下Facebook Groups,你会感觉跟用Native App的体验没有什么区别。在开发的过程中JS可以脱离VM来跑,并通过JSON等的序列化来进行通讯,在React Con上的演示就是这样,他们可以直接用Chrome Developer Tools对App的JS代码进行调试。
可以看出我先前对React Native的预测基本都说中了,它实现了去WebView化,用iOS原生组件作为Viewer的Render Engine,JS代码虽然没有编译过但是执行效率还不错。从开发体验上来看,React Native提供了一套非常完整的开发Workflow,基本上你只要一直跑着iOS Simulator,更新代码后在Simulator中Cmd-R一下就能刷新App,基本不需要进行编译。我在想,这样一来其实一定程度上还能做到App内部的自主更新不是吗?只要把最新的JS代码拉下来就能放到VM里面跑了。就是不知道App Store会不会允许这样的更新机制。
App的Test也可以完全用JS来写,而且理论上来说Test的Context与Render环境无关,可以脱离iOS直接在本地的Node.js上跑,这对于程序的调试来说也是一种便利。开发者可以在非Mac系统下进行Test-driven的开发而不需要去考虑iOS的具体环境。
当然,从文档的各种留白我们可以看出React Native现在还处于非常初期的摸索阶段,还有很多iOS Framework下的东西没有很好地整合进去。但是FB已经向我们Proved the Concept,并且消除了人们对效率和兼容性的担忧。我觉得在现今的基础上做更深一步的融合是相当迅速的,我相信在接下来的几个月中我们将看到新一波的Paradigm Shift出现在移动App开发领域。
========== 更新 =========
看到 @rank 把react-canvas都扔出来了我不得不来唠两句了。我也是这个星期才在HN上看到的这个项目,实际上这个项目一周前才发布出来。不得不说这的确是一个很赞的实现,我也见过一些用canvas写的网页,对移动端的适应做得非常好,比如这个Legend就设计得很酷炫。
但是,从我目前了解到的信息来看,react-canvas在制作规模化移动端应用方面并不能赶超React Native的势头,原因如下:
React Native的目的在于让原本用WebView做的App去掉DOM渲染层,用更加原生的界面元素和渲染引擎提升性能。但是如果用react-native的话则仍旧没有脱离WebView,两者的运行时体积可见一斑。而且这加多一层东西必然对性能有所影响,比如你用Native的方式做Transition Animation,在动画的实现方面不需要由你的代码控制,可以直接使用渲染引擎的自带动画,就算有些自定义动画也不必再JavaScript上面运行,因为React Native已经将JS编译成了Native的二进制来执行了,所以又减去一层JS虚拟机的效率损耗。再看react-native,你要跑canvas就不得不用WebView,不得不使用原本的JS引擎去驱动整个界面,你不得不将所有的控件、Layout、Animation全部在JS层面实现一遍,并全权交由JS来控制,这个计算开销不是一般的大。你如果仅仅为了保留WebView、JavaScript的情况下使用canvas硬件加速而去增加这么多中间层,实在不是一种理想的趋势。
由于内容需要在canvas上渲染,那么有可能会遇到一些写游戏的人喜闻乐见的问题,比如CJK字体渲染。还有很多Accessibility方面的硬伤,比如canvas里面的文字没法选中、复制或者使用系统的Define功能查词,也无法兼容读屏程序。在Flipboard的例子中他们的解决这些问题的方法实在是太Dirty了,他们用回了DOM元素,用DOM渲染文字,然后悬浮在canvas上面,这样用户就能对文字进行Native的操作。但是这样的解决方法根本就是在倒退回DOM的开发模式啊好吗,为了达到上面的效果,他们还得在后台代码构造一个Virtual DOM Tree,实时跟canvas的内容同步,然后更新DOM的内容和style。这样的做法简直无法理喻,如果说canvas能靠硬件加速提升性能,你把DOM跟canvas混用那这个效率还能提升多少?再说如果用DOM画的部分要与canvas上的内容作更复杂的互动,用DOM是根本没法渲染的。引用react-canvas作者的话来说就是:“pushing the browser beyond its limits that we can make progress in this area.”所以这个项目到底有多Dirty作者本人也是知道的。
相比之下,React Native致力于去掉更多的中间层,只保留一个Flux+React的中心概念,这才是一个合理的发展趋势。我见到有人说React Native跟react-canvas两者不冲突,可以用canvas做React Native的渲染引擎。说这话的人还是没有认识到React Native的目的究竟在哪。我说了React Native在于去掉中间层,你又要用回canvas再加上一个WebView和一堆JavaScript,那React Native的意义何在?就好比乔布斯千方百计把iPhone的厚度减少了一毫米,你带个套又给人加回去了一样。
======== 原答案 ========
看了所有的答案,都没有讲清楚React的实质作用在哪。
我上周用纯React完成了一个CMS发布系统的界面框架,数据层仅仅用了Parse的JS库,但是功能还算完备。中间读了不少这方面的资料,对Flux + React有了一个较为系统的了解。这里大致总结一下给还没开始动手写React的人一点启发。
要讲React的实质作用那一定不能脱离Flux模型。一说到Flux,很多人的第一反应就是那个经常见到的、看起来很复杂的Loop流程图。我不想一开始就贴那张图,因为我默认你们都没真正用过React,那张图只能让你们更加不明觉厉。其实了解Flux + React最好的方法就是看看官网给的这个视频,我就把重点摘出来讲讲吧。
首先,Flux是为了解决MVC模型中数据流向不一致的问题的。视频中给出了一个非常典型的案例,可以说我以前也被类似的问题折腾了好久。比方说你从服务端拉下来的数据要改变两个View的内容,比如给未读消息的数字提醒+1,然后把消息放到Chat View中,如果用户正在看当前的Chat View就把未读消息数字-1。这一连串的操作在没有用React的时候要怎么写?她给出的代码也是我以前处理类似状况的方法:
我以前也不是没想过写一个MessageManager之类的,类似Flux的Dispatcher一样的东西去控制这些逻辑然后分别对不同的View进行改动,但是好好想想这不过是一个简单的信息接收而已啊,为啥要复杂到专门给一个数字写一个Dispatcher去做这种事情?所以最后想想还是算了,代码丑点就丑点,能用就行,最后我也写成上面那样了。但是你要知道,这样的代码写在异步程序里是非常危险的!如果用户同时在操作,那你的代码很可能就会被中断报错的。还有,如果后期需要加功能,比如在屏幕侧边再搞个信息框,那你怎么知道在哪去加代码?你程序的数据交换会像这样混乱:
怎么样?写异步MVC的童鞋有没有感同身受?脸书以前的Chat就是经常因为异步数据的问题被人黑。比如经常是右上角一个红色的1,点进去一看啥都没有,强迫症的怒火你可晓得?
那么问题来了:如何让异步数据像同步数据一样正确地显示出来?脸书的攻城狮想到一个绝妙的招式:咱别一个DOM一个DOM的去更新内容了,来一次数据俺们就“刷新”页面!是的,就是回到了90年代的那种模式:你想看新邮件?请刷新页面!然后服务端把你当前的邮件全部读一遍,排好序,生成好HTML,然后给你寄过来,你就能看到新邮件啦。Flux就是这么干的,只不过现在已经是21世纪了,渲染HTML这种工作不需要服务端也能做,我们也不用真的去刷新整个网页,虽说Chat的那个问题的确可以靠刷新页面解决掉lol。Flux的(大致)做法是:来新的数据了,好,我把它Merge到客户端的旧数据中,然后把客户端存着的所有数据交给一个Render,然后把整个HTML从头到尾渲染一边,最后把新的HTML替换掉现有的HTML就好啦!那么之前那个Chat的代码咱就可以这样写(我YY的,视频没有,也不是React代码)
function newMassageHandler(newMessage)
this.messages.push(newMessage);
this.renderTheWholePage(); // In practice it should be an Action Creator
看到没有?管你有多少个View,你们自个儿去算怎么渲染吧,handler只管存数据跟提醒渲染。如果哪个View计算完了说,不对,那个Unread Message Number要-1,好,你跟Action Creator说一声,他会在下一轮渲染前把这个项目加到数据中的。如此一来就不会出现把改动View的代码写到某个Controller中,然后一个Controller又要同时关联好几个View的情况,这样一来整个程序的结构就变得非常清晰了。这时候再看这张图就容易理解多了:
数据的流向变得非常统一,如果View要对数据做些改动也得等整个View渲染完了在下一轮渲染的时候再改,从而形成一个非常完整的Loop,这对异步数据的处理是非常有帮助的。
Flux是一个取代MVC的设计模式,而React就是脸书写的给Flux用的专门做Viewer的框架。由于Flux要将原有的HTML从头到尾渲染一边,那么就不得不考虑一个平滑过渡的问题,因为毕竟我们要讲究用户体验,不能每次收到数据就真的把原网页给删了然后重新给用户画一个,那用户还不崩溃啊?React解决这个问题的办法就是用Virtual DOM,这才是React真正的核心价值。其原理是写看起来像是DOM的JS代码,然后生成ReactDOMElement的对象,而不是真正的DOM,然后把新的Virtual DOM Tree跟用户正在看的DOM Tree做个Diff,然后用最小的改动量Update整个网页。对比一下jQuery大概就是这样:
// jQuery
$(‘‘).text(‘Submit’).on(‘click’, submitHandler);
// Submit
// React without JSX
React.creatElement(‘button’, onClick: submitHandler, ‘Submit’);
// Submit
// React with JSX
Submit
可以看到,其实JSX只是React的一个语法糖,这只不过是一门DSL。有些人一看到JSX就说把HTML写JS里了,我真是不知道该怎么评价这种人。ReactDOMButton并不是真的DOM,在运行时只是一个普通的JS Object,我写成XML形式只是易读。不用真的DOM当然是因为效率问题,这也是一种优化手段,但是Virtual DOM的好处当然不止这样,后面会讲。
你要是不喜欢JavaScript也没事,我就不喜欢。知道GitHub的Atom吗?就是用CoffeeScript + React写的。它并不是用改过语法的那个看起来就很恶心的coffee-react项目,而是自己写了一个很简单的helper来做简单的Transform。大致的原理是这样的:
div, button = require(‘react’).DOM
div
className: ‘message’
onClick: @messageHandler
‘some messages’
button()
我觉得这样的写法真的很简洁很优雅,而且一想到这写的根本就不是HTML也没碰一行JavaScript就觉得很开心啊。不过我是LiveScript党,有更加简洁的语法,把Atom的helper改了改现在用在别的项目中用得很方便。
看到这样的写法观众就应该很清楚地明白了React的原理了吧,它实际上就是把DOM元素全部变成了JS的类,可以直接用JS等价的代码调用new出来。(实际上是要用一个factory包着才能用的,0.12后把createFactory整合到createElement里面了所以现在用法上更加简洁)
但是千万不要以为React就只是JS世界中的东西,其实它也是受到别的领域的启发呢。上面那个视频中后半段详细介绍了React,其实React这种idea受启发于游戏的渲染。有很多游戏都是数据来了,跟现在的数据Merge一下,然后update数据结构,diff一下老的结构,然后再部分渲染。所以说React其实最重要的还是一种使用Virtual Element描述界面的方式,而因为这种方式容易进行二次计算,所以能够保证最小幅度的影响用户体验,最大幅度地保证数据跟界面的一致。因此React才能够很轻易地使用在后端,做给Spider渲染HTML的工作。要知道Angular在之前是做不到这一点的,对搜索引擎的优化竟然要用到PhantomJS!而且这种方式竟然还演变成了收费的服务!简直让人咋舌。但是React却能做到,因为它并不受限于JavaScript,脸书最先用React做后端的时候是PHP的,后来整合Instagram的时候才分离出来写了开源的JS库。
所以我觉得React Native的最终形式并不仅仅是把Web做到移动端上,因为那样根本没法跟Native的比。而是要把React这种Viewer的架构在Native上实现,把原有的模板式UI重构成Virtual Elements,然后以更加动态的方式渲染。不过就目前的开发进度来看,这个目标还是遥遥无期。
以上。
编辑于 2015-03-27 20 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
57
赞同反对,不会显示你的姓名
孙士权,Web Dev / ZJU / http://imsun.net
fall rain、刘子明、知乎用户 等人赞同
哈哈,大家都不看好它,我倒是觉得它非常不错。
先说一下传统的 hybrid app 的一些优劣势:
优势:js 可以直接被 native 端执行,也可以和 native code 进行通讯,进而可以调用一些 native 提供的接口。 能直接被执行的好处在于可以直接从服务器上载入并执行 js 代码,这点在 iOS 上是 native code 和其他 to objc 的语言都难以做到的。这使我们有了一些更灵活的方法,来完成诸如应用内更新或者开发应用内插件之类的工作。同时,iOS 和 Android 可以共享一些前端部分的代码,使得代码能够更好地重用。
劣势:界面渲染效率低,多线程支持差,GC 问题。在 WebView 中绘制界面、实现动画的效率都比较低,开销也比较大。WebWorker 提供的多线程在 native 端有很大的局限,js 在 GC 时也有可能卡 UI。
React Native 的做法非常激进,完全抛弃了 HTML(抛弃了 HTML 不代表抛弃了声明式),抛弃了 WebView,在 background thread 里运行 js 并直接使用原生控件进行渲染。
这从根本上解决了渲染问题,使得 js 不再只能做 hybrid app,而能做出具有 native behavior 的流畅靠谱的 native app。从这一点上来说 React Native 已经做得相当不错了,尽管它只实现了 CSS 的子集,但是考虑到 CSS 如此复杂而它又抛弃了使用 webview 渲染,这是可以接受的。
===========
但是,React 的意义绝不在于解决了一些 hybrid app 的痛点。
React 是一个很有野心的项目,它的目标不仅仅是简单地使前端能用 js 写 native app,而是希望推广一个通用的前端构建方案,不论是 Web 前端,还是客户端前端。
FB 在演讲里说,React 的目标不是 “Write once, run anywhere”,因为不同平台的差异是客观存在的,设计风格也各有不同。它要做的,是 “Learn once, write anywhere”。React 里的 view 不仅可以是 DOM,也可以是 iOS 控件或者 Android 控件,不论是什么平台,都能 “build in React”。
就我看来,前端不只是需要写网页,更重要的是要解决属于前端领域的各种问题。Web 前端和客户端前端在本质上是一致的,探索前端领域的最佳实践是一件很有意义的事。
近些年前端比较火,相比于自成体系较为封闭的客户端前端, Web 前端在前端实践上的探索或许更多一些。不管是阿里的 Midway 那样侵入到后端的 UI layer,还是像 React Native 这样侵入到客户端前端,我认为都是非常值得称赞的探索。
至于到底怎么评价 React Native,我觉得它和 React 一样赞。
===========
最后附个 FB 关于 React Native 的演讲:https://www.youtube.com/watch?v=KVZ-P-ZI6W4
发布于 2015-01-30 4 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
12
赞同反对,不会显示你的姓名
周攀(Henter),http://henter.me
Razer、刘成龙、mfive 等人赞同
henter/ReactNativeRubyChina · GitHub
henter/ReactNativeRubyChina · GitHub
发布于 2015-04-10 添加评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
5
赞同反对,不会显示你的姓名
林蓝东,Cocoa / Ruby Developer
VeraChen、知乎用户、张一峰 等人赞同
Why React Native Matters · joshaber 这篇文章的观点比较认同,使用 Javascript 只是一个实现细节:
React lets us write our UIs as a pure function of their state.
This is a big, important idea.
Right now we write UIs by poking at them, manually mutating their properties when something changes, adding and removing views, etc. This is fragile and error-prone. Some tools exist to lessen the pain, but they can only go so far. UIs are big, messy, mutable, stateful bags of sadness.
React let us describe our entire UI for a given state, and then it does the hard work of figuring out what needs to change. It abstracts all the fragile, error-prone code out away from us. We describe what we want, React figures out how to accomplish it.
UIs become composable, immutable, stateless value types. React Native is fantastic news.
实际上 Facebook 在之前也用 Objective-C++ 开发了一套类似现在 React Native 的框架 Components 用于 Facebook for iOS,在 The Functional Programming Concepts in Facebook’s Mobile Apps 这个演讲很好地解释了这种模型的优势。
发布于 2015-02-27 2 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
10
赞同反对,不会显示你的姓名
老谭,想用React Native写Android APP的服务端…
知乎用户、Grace Yang、朱俊 等人赞同
尝鲜用react native 开发了个简单的新闻APP (tabalt/ReactNativeNews · GitHub),用着还挺爽的,遇到的问题也基本能在 官方github的issue里面找到答案。
我觉得最重要的是大大降低了开发native app的门槛与学习成本,像我这样会点JS的PHP码农,本身服务端要深入学习的东西就非常非常多,想赶时髦玩玩APP开发,非得要我再去学OC和Swift或者Java么?
说实话,OC的语法着实不喜欢。有学Swift的功夫,我还不如好好练习下Golang。Java虽然学过,但也早就还给老师了。在各种语言中切换,有时候还真不是一下子能缓过神来。另外除了语言,还得学各种iOS、Android系统相关的特性,还要学两个平台下怎么画界面。
说白了,我想做的APP就是画几个界面而已,这事我用HTML、CSS、JS 干得已经够顺手了,hybrid的形式,性能又是硬伤。因此React Native刚出来的时候我就在等发布,一发布就迫不及待的去玩了一把,确实没有让我失望。
期待安卓版早日到来~
发布于 2015-04-07 6 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
51
赞同反对,不会显示你的姓名
端木文,JS語言研究,原理探究,應用優化
cp zheng、Zhang oli、张洪亮 等人赞同
我先来答吧。
从很久以前就警告了用HTML5来做App有多不靠谱,不过各种Cloud还是不断出现。
说到底,HTML5做App的优势和劣势都是HTML本身,或者说是DOM,成也萧何败也萧何。
归功于CSS这个神器,UI制作变得非常简单而强大。但是却因为DOM这个东西,每次操作都比Native View慢很多,内存开销也很大。
========分割线========
- ReactJS在JS圈子里的口碑在不断爬升(虽然我没用过),组件模式的开发体验对Native App来说非常适合。
- React Native宣称抛弃了DOM,而是纯净的JS Binding。但我还在怀疑他们是打算先用HTML做一次转换,还是直接修改React的体验,适配Native View。如果是后者,相信会非常棒。
- 还需要看看他们用的JS引擎,还有针对Mobile App的优化,比如GC。
- 从我个人角度看,FB把JS Binding和View Binding这套东西开源出来,比React自身更有意义。
看了@小芋头君 的回答,继续说下。
现在确实各方神仙都想用自己的玩具来做本来不属于他们的领域,比如iOS。
作为一个长期从事JavaScript开发的人,现在因为需求,要做iOS的开发。可能会有很多人想,有很好的前端能力,用HTML5来做会适合。但我没有这样做,而是买了一本Swift的书,重新学习一门语言。
PS: 个人不太喜欢OC的语法,Swift对我来说基本可以跳过语法学习。
就如上面说的,我了解完全用HTML5做App的危险性:维护成本,可用性,性能等等。有时候,学习相关的东西比用不相关的东西更来的快,更何况Swift很友好。
我想说的是,跟风、傍大款是阻碍程序员进步的品质。
还有,别把糖果当成银弹了。
编辑于 2015-01-30 20 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
1
赞同反对,不会显示你的姓名
伏圣文,I love software.
tomisacat 赞同
Titanium (http://www.appcelerator.com/titanium/) 就是和 React Native 一样的逻辑,用 js 调用原生控件。
这样很好,解决了界面体验问题。
不过也有没解决的问题。他们无法代替原生的 API,很多效果,开源的控件,都要用原生的代码来实现。
简单的 app 没什么问题。遇到复杂的 app,还是原生代码来的靠谱。
发布于 2015-01-31 添加评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
5
赞同反对,不会显示你的姓名
Googol Lee,程序员
知乎用户、李飞、知乎用户 等人赞同
Qt已哭晕在厕所
发布于 2015-09-25 添加评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
Jim Liu,熊掌社前端码畜,INTJ,各种打自己脸
心情掉线、张亚鹏、吴毅凡 等人赞同
现在趋势都是声明式UI,React却“反其道而行之”,把UI深绑定到JS中去。
然后又嫌编程创建控件的方式,对于UI的树状结构太麻烦了,于是搞出了个JSX。
我就纳了闷了,他们团队究竟是对JS有多执念?
诚然,以现在的前端生态来看,JS的群众基础的确是好。
但是用React以后,要尽量保证与传统DOM的绝缘(下文例1)。从ReactJS的Virtual DOM,到React Native的“No DOM”(引号是因为这词不是官方的)。对JS群众而言是个新的挑战。(而且JSX真的是不怎么不好用啊)
因为还没有看到第二天的视频,具体的一些实例代码和技术细节都看不到,但从现在的理解看,它仅仅是用了JS而已,跟前端技术已经没什么关系了,东西都要重新学。这方面我会继续关注后面的视频。
然后另一方面,因为我不会做Native开发,不知道各种控件样式一般而言是用什么来定义的,但是如果React Native要搞一套“Native CSS”,这又是个学习成本,同时也是个无底天坑了。
定义样式这方面,昨天的视频里没有看到,今天的视频发出来了之后我会再关注一下。
小结:
React Native除了JSX以外,已经和JS的发源地——WEB前端技术没太大关系了,东西都要重新学。
它并不能提供一个用Web的技术和经验来开发NativeApp的方式,这一点与Ionic有本质区别。
前端开发者想因此快速做出Native开发,也许做做小样还行,做出严肃的产品,我认为还有距离。
结论:我不认为这是一条给前端转Native的出路。
上文例1
一些UI控件,比如模态框,很常见的实现方式是把模态框从定义的节点里摘出来,塞进BODY里面,这样定位什么的非常好搞。
氮素,这样做会破坏真实DOM与Virtual DOM之间的关联关系,ReactJS会罢工。
例如SemanticUI中的modal组件,需要指定detachable
才能让它不把元素剥离进BODY里去,SemanticUI的文档中说这样做会造成渲染获得更少硬件加速的优化。
这还是人UI组件库设计的比较周到,如果是要捡着自己的组件库用,还不知道要踩多少坑。
相比之下,Angular要友好一些,我们写的UI组件自己接管状态维护之后,只需要修改
scope,然后调用
apply,把状态维护交还给它的digest循环就行了。具体就不展开讨论了。
发布于 2015-01-30 6 条评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
2
赞同反对,不会显示你的姓名
Alsey,软件技术工作者
杨东、Daneel Olivaw 赞同
react native做了两件事,一件是react,一件是native。
react的核心是组件化,组件化的优势是复用和可视化开发。这样就很容易形成类似visual studio这样强大的界面开发工具。其实,react走组件化的路线更多是为了提供抽象的界面层。有了抽象的界面层就为后续实现大一统的开发环境迈出了第一步。
native可以称其为小型虚拟机,或是实时解释器。它的出现就是对底层native的屏蔽。因为没有类似于java的编译步骤,所以就是write once, run anywhere,本质上和java虚拟机是一样/类似的。
就此看来react team的目标肯定是做一个大一统的开发平台,对不同的操作系统,web和native兼容并包,那么react native是其中的第二步。
发布于 2015-02-04 添加评论 感谢 分享 收藏 • 没有帮助 • 举报 • 作者保留权利
2
赞同反对,不会显示你的姓名
張開宇,RoR贡献者,Emacs贡献者
孤独惟者、知乎用户 赞同
React Native的功能很强大。最重要的,学习一种开发方式,可以开发各种平台的前端。
如果想找一种一次代码,多次执行的,可以来体验这个框架。
https://github.com/cheunghy/CocoaBean
它跟React Native有不同的理念。CocoaBean志在一次代码,多次执行,并且代码风格跟本地开发MVC一模一样,适合小团队创业,尤其是新闻评论分享app和展示app。
以上是关于知乎上关于ReactNative的评论汇总(网友们有才哟...)的主要内容,如果未能解决你的问题,请参考以下文章