为什么选择React-native
1、React-native的背景
Facebook
创建了 React-Native(RN)
来构建 app
。它最初是在2013年的夏天在 Facebook
内部的一个项目,2015年成为开源项目,是因为当时 React
在社区的呼声很高,他们就觉得 React
是一个很好的UI
框架,那么如果你想构建一个 native-app
,为什么不直接让在 React
跑在移动端的操作系统上那!
因此,在同一年,Facebook
将 React
分为两个独立的库,也就是 React
和 React-dom
,可能大伙对这个概念还挺模糊的,我简单解释一下。
React
: React
是一种用于构建用户界面的 JavaScript
库。它是一个核心库,用来创建 React
元素 (elements
)、组件 (components
) 和虚拟 DOM
(Virtual DOM
),并在应用程序中管理组件的状态和生命周期。React
可以在客户端和服务器端使用也包括了React Native
。
React-dom
: React-DOM
是 React
库针对浏览器的针对 DOM
操作的补充。React-DOM
提供了与 DOM
相关的功能,比如把 React
组件渲染到 DOM
中,处理用户交互等事件。
简单来说,React
库提供了一个基础构建组件树的库,而 React-DOM
则为你提供了一些针对 Web
页面的工具,如将组件渲染到网页中,并支持通过事件响应来进行交互。
从那时起,React
就不用关心组件的渲染在哪个平台上。Web
平台的渲染由 ReactDOM
承担,而移动平台的渲染由 RN
承担。
2、什么是React-native
RN
是一个基于 javascript
的跨端框架,RN
提供了一套代码多个平台运行的能力。
它最开始解决的问题是,在安卓上,开发者需要实现一套Java app
,又在ios, 需要实现Swift
,我们就需要学习两门语言,去实现一个完整的app
。
那时候就感觉像是这样的。
web
开发者要了解HTML
,CSS
,JS
,React
安卓
开发者要了解Java
,Kotlin SDK
ios
开发者要了解Object-c
,Swift
,CocoaPods
.
而在R系大家庭中,React-native
应运而生,引入一个新的platform
去平替
上者后2。
它现在看起来是这样的
这就是我前面讲到的,React
仅仅是管理Fiber树,em或者说组件树
,而渲染交给了react-dom
或者react-native
。
我们进一步研究一下,究竟是如何在我们的app
上跑的,rn
其实是用React
、Js
去调用native组件
然后构建app
。例如,<Image/>
组件代表了另外两个本地组件, 安卓的ImageView
、iOS的UIImageView
。在这rn
的架构中是由两个线程控制的,一个js
线程、一个native
线程。
- 首先我先讲一下
js
线程的东西,我们先有个概念,举个例子:我们的浏览器用虚拟引擎去执行js
代码就像是v8
。意思就是我们的代码如果要跑在rn
上同样需要一个虚拟引擎
,去执行我们的api
、处理我们的事件。在最开始就是ios
内置的JScore
这个引擎,但这个引擎在打包安卓的时候会把包搞大,又用不上,所以就在0.6这个版本后采用Hermes
这个新引擎,在0.64后ios也采用这个引擎了,毕竟它确实更好,如下它的优势。
-
更快的启动速度。
-
更小的包。
-
内存使用更小。
与浏览器中一样,rn
中的JS
是在单个线程中实现的。该线程负责执行JS
。我们正在编写的业务逻辑将在这个线程中执行。这意味着我们所有的通用代码
,如组件、状态、钩子和REST API
调用,将在应用程序的JS部分中处理。
- 那么
native
线程是做啥那,其实就是执行native
代码的地方,rn
它在每个平台(java
、oc
、ios
)上都去实现了这一部分,这个线程绝大部分的内容都是与安卓ios
通信的sdk
,同时为我们提供统一的api
。举个例子:就是比如我调用一个alert
弹窗,native
层就整合了2个平台提供了一个统一的api
,然后我们在js
线程中去调用他。实际上这是线程的交互,在native
线程的角度来看,就我们要弹出个警告,他其实是两个部分,Native ui
去更新页面,Native Moudles
去访问平台特有的功能。
上面我们说了一下两个线程分别是干啥的,紧接着就肯定离不开线程之间的通信
,而这两个线程之间的通信是通过桥(就这么理解吧)
,这个桥
是用C++
写的,并基于一个异步队列。当桥
从其中一方接收数据时,它将其序列化,将其转换为JSON字符串,然后把它排在队列中。在到达目的地后,数据就被反序列化。
就以上面的alert
为例,native
接受来自JS
的回调并显示该对话框。实际上,JS
方法在被调用时,向桥发送消息,并接收到到消息时,native
执行指令。本机消息也可以被转发到JS
。例如,单击该按钮时,native
向js
发送一个单击事件消息。就大概像这样:
大家应该很容易发现问题,就是因为所有的事件都依赖于异步的桥去完成通信,那可能会面临就是说队列负载过高,就导致的性能问题,但确实也存在,只能说有利有弊了,我们先留下这个悬念,后面再看看RN
的架构中是如何处理这个问题的(下一篇再讲新架构内容太多了)。
其实RN
使用就是使用异步回调去操作底层的移动端操作系统,也就是调用原生的api
。rn
有一个JavaScript
引擎,并且RN API
与Web
的React
基本相同,区别在于原生端;Rn
是异步调用的原生API,而不是DOM。如图所示:
RN
使用与web
上使用的相同React
库(也就是前面提到的React
核心库),并在JavaScriptCore
中运行。- 发送到
Native api
的消息是异步和批处理的。 RN
附带了为移动平台实现的组件,而不是HTML元素的组件.RN
其实代表的是通过iOS
和Android
api渲染组件的方法。它可以用同样的概念来在tvOS
、电视、Windows、macOS,甚至是Web上渲染。
3、使用React-native的优势
为React
去实现一个新的渲染其实还挺难的,就大伙想象一下这就像发明一个可以运行在ios
和Android
的新的dom
难度,但跨端应用还是不得不做,就我想了一下有这几个原因吧。
- 最重要是还是需求催生了技术,因为移动端的巨大需求,而H5性能的不近人意(就是用户体验差),而
rn
这种其实算是变相调用原生的api
会好很多。 - 然后就是
jsx
,可能我对flutter
的好感不如rn
的原因就是因为这个吧,学习成本低了。 - 商业价值洛,这些年客户端混成啥样不用我多说了吧(但从另外方面来说还是得要人做一些桥接的东西)。
4、自我感觉Rn的哲学
就这里只谈谈自己对RN
的感觉。
怎么说那?就是可能大家觉得rn
,应该就是你可以用react
的语法写一个跑在任何原生设备上的应用。
但不行,因为ios
和安卓
在许多最基本的层面就是不一样的,甚至它们的UX
哲学完全不同(这其实也是ios好很多的原因),所以其实想写一个不处理两种情况的单一app
其实还真不行。
简单的说就是,rn
不是实现一个组件库让你在任何地方跑,它处理的只是native
重叠的地方。rn
不是写一次,就可以在任何地方跑(除非你完全不在意用户体验),它应该说是学习一次,写在任务地方。你需要在某些情况,用特定ios
/安卓
组件,去提供更好的UX
(但其实rn
已经帮你处理很多差异和提供很多通用基础组件了,只是你可能需要脑子里对平台差异有个类似于红线认知的东西)
5、谈谈产品与app
其实对于用户来说, web应用
的门槛是远远低于 app
的,如果没有强需求大伙是并不愿意安装一个发灰的 app
,大伙应该更喜欢一个浏览器去看一些东西,尽管没app体验好
。
假设这时候我有一个c端产品
,我们该怎么去选择它的平台那?
1、Pc web。
2、移动端 web(平板、手机)。
3、移动端app。
如果是一个功能复杂的大产品
一定要选择app
,而如果是一下小巧功能单一的产品就可以选择移动端web
。我从技术的角度谈谈为什么
移动端浏览器是缺乏移动应用程序许多功能的。这是因为浏览器的HTML元素不能与原生的组件保持一个UI和交互的同频
。虽然我们可以试着去还原,但太麻烦了。
然后就是移动设备上的用户交互与通常与h5的交互有根本的不同。例如:web的点击事件,点击一个按钮上的事件只是一个阶段。然而,当用户使用手指与屏幕交互时,人是一直滑啊(你要算各种touch x y什么的)。原生有一个专门的手势系统让它来处理这个问题。而web
会让这事异常复杂。
简单的总结一下
1、移动端浏览器,UI和交互与原生的不统一,甚至有的设计会提出在移动端上写表格这种事情,但说实话这完全不该是移动端体验的一部分。
2、web应用缺乏很多原生能力,就像上面举到的手势系统等。
6、结束
因为最近业务在写Rn
,就正好巩固一下一些知识,也增强大伙的竞争力,后面估计这个部分会出很多章,想这种概念的东西还挺重要的,大伙可以吸收一下。呜!就你想成为强者吗!那就来一起学习吧,->看这里沸点。
转载自:https://juejin.cn/post/7223204251005239354