选择 React-native 的一些理由 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leia
V2EX    前端开发

选择 React-native 的一些理由

  •  
  •   leia 166 天前 1888 次点击
    这是一个创建于 166 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文总结:

    运行机制 React Native 的运行机制基于两个线程之间的通信( Javascript 线程和 Native 线程),通过 Bridge (桥) 实现数据交互。这使得 JS 逻辑与原生界面可以协同工作,实现流畅体验。

    优势

    • 学习成本低,Javascript 和 React 开发者可以快速上手
    • 满足大部分产品需求,适用于多数中小型 App
    • 代码复用性高,节省开发时间与人力成本
    • 有大量 开源组件 和社区支持,发展活跃

    哲学与设计理念 React Native 并不是完全跨平台,而是通过处理 Native 重叠部分来实现最大化复用代码。它强调 “Learn once, write anywhere” 而不是 “write once, run anywhere”。

    平台选择的考量 文章也提到在选择 React Native 还是原生开发时,需根据产品的实际需求、团队技术栈、性能要求等因素综合考虑。例如:

    • 对性能要求极高的应用建议使用原生开发
    • 对开发效率和跨平台需求强烈的项目更适合 React Native

    1 、React-native 的背景

    背景与定义 React Native 是由 Facebook 创建的,基于 Javascript 的跨平台开发框架,旨在帮助开发者使用一套代码同时构建 iOS 和 Android 应用。

    Facebook 创建了 React-Native ( RN )来构建 app。它最初是在 2013 年的夏天在 Facebook 内部的一个项目,2015 年成为开源项目,是因为当时 React 在社区的呼声很高,他们就觉得 React 是一个很好的UI 框架,那么如果你想构建一个 native-app,为什么不直接让在 React 跑在移动端的操作系统上那!

    因此,在同一年,FacebookReact分为两个独立的库,也就是 ReactReact-dom,可能大伙对这个概念还挺模糊的,我简单解释一下。

    ReactReact 是一种用于构建用户界面的 Javascript 库。它是一个核心库,用来创建 React 元素 (elements)、组件 (components) 和虚拟 DOM (Virtual DOM),并在应用程序中管理组件的状态和生命周期。React 可以在客户端和服务器端使用也包括了React Native

    React-dom: React-DOMReact 库针对浏览器的针对 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其实是用ReactJs去调用native 组件然后构建app。例如,<Image/>组件代表了另外两个本地组件, 安卓的ImageView、iOS 的UIImageView。在这rn的架构中是由两个线程控制的,一个js线程、一个native线程。

    1. 首先我先讲一下js线程的东西,我们先有个概念,举个例子:我们的浏览器用虚拟引擎去执行js代码就像是v8。意思就是我们的代码如果要跑在rn上同样需要一个虚拟引擎,去执行我们的api、处理我们的事件。在最开始就是ios内置的JScore这个引擎,但这个引擎在打包安卓的时候会把包搞大,又用不上,所以就在 0.6 这个版本后采用Hermes这个新引擎,在 0.64 后 ios 也采用这个引擎了,毕竟它确实更好,如下它的优势。
    • 更快的启动速度。
    • 更小的包。
    • 内存使用更小。

    与浏览器中一样,rn中的JS是在单个线程中实现的。该线程负责执行JS。我们正在编写的业务逻辑将在这个线程中执行。

    这意味着我们所有的通用代码,如组件、状态、钩子和REST API调用,将在应用程序的 JS 部分中处理。

    1. 那么native线程是做啥那,其实就是执行native代码的地方,rn它在每个平台(javaocios)上都去实现了这一部分,这个线程绝大部分的内容都是与安卓 ios通信的sdk,同时为我们提供统一的api。举个例子:就是比如我调用一个alert弹窗,native层就整合了 2 个平台提供了一个统一的api,然后我们在js线程中去调用他。实际上这是线程的交互,在native线程的角度来看,就我们要弹出个警告,他其实是两个部分,Native ui去更新页面,Native Moudles去访问平台特有的功能。

    上面我们说了一下两个线程分别是干啥的,紧接着就肯定离不开线程之间的通信,而这两个线程之间的通信是通过桥(就这么理解吧),这个是用C++写的,并基于一个异步队列。当从其中一方接收数据时,它将其序列化,将其转换为 JSON 字符串,然后把它排在队列中。在到达目的地后,数据就被反序列化。

    就以上面的alert为例,native接受来自JS的回调并显示该对话框。实际上,JS方法在被调用时,向桥发送消息,并接收到到消息时,native执行指令。本机消息也可以被转发到JS。例如,单击该按钮时,nativejs发送一个单击事件消息。就大概像这样:

    大家应该很容易发现问题,就是因为所有的事件都依赖于异步的桥去完成通信,那可能会面临就是说队列负载过高,就导致的性能问题,但确实也存在,只能说有利有弊了,我们先留下这个悬念,后面再看看RN的架构中是如何处理这个问题的(下一篇再讲新架构内容太多了)。


    其实RN 使用就是使用异步回调去操作底层的移动端操作系统,也就是调用原生的apirn有一个Javascript引擎,并且RN APIWebReact基本相同,区别在于原生端;Rn是异步调用的原生 API ,而不是 DOM 。如图所示:

    • RN 使用与web上使用的相同React库(也就是前面提到的React核心库),并在 JavascriptCore中运行。
    • 发送到Native api的消息是异步和批处理的。
    • RN附带了为移动平台实现的组件,而不是 HTML 元素的组件.
    • RN其实代表的是通过iOSAndroid api 渲染组件的方法。它可以用同样的概念来在tvOS、电视、Windows 、macOS ,甚至是 Web 上渲染。

    3 、使用 React-native 的优势

    React去实现一个新的渲染其实还挺难的,就大伙想象一下这就像发明一个可以运行在iosAndroid的新的dom难度,但跨端应用还是不得不做,就我想了一下有这几个原因吧。

    1. 最重要是还是需求催生了技术,因为移动端的巨大需求,而 H5 性能的不近人意(就是用户体验差),而rn这种其实算是变相调用原生的api会好很多。
    2. 然后就是jsx,可能我对flutter的好感不如rn的原因就是因为这个吧,学习成本低了。
    3. 商业价值洛,这些年客户端混成啥样不用我多说了吧(但从另外方面来说还是得要人做一些桥接的东西)。

    4 、自我感觉 Rn 的哲学

    就这里只谈谈自己对RN的感觉。

    怎么说那?就是可能大家觉得rn,应该就是你可以用react的语法写一个跑在任何原生设备上的应用。

    但不行,因为ios安卓在许多最基本的层面就是不一样的,甚至它们的UX哲学完全不同(这其实也是 ios 好很多的原因),所以其实想写一个不处理两种情况的单一 app其实还真不行。

    简单的说就是,rn不是实现一个组件库让你在任何地方跑,它处理的只是native重叠的地方。rn不是写一次,就可以在任何地方跑(除非你完全不在意用户体验),它应该说是学习一次,写在任务地方。你需要在某些情况,用特定ios/安卓组件,去提供更好的UX(但其实rn已经帮你处理很多差异和提供很多通用基础组件了,只是你可能需要脑子里对平台差异有个类似于红线认知的东西)

    5 、谈谈产品与 app

    对于用户来说,Web 应用的使用门槛远低于 App。如果没有强需求,大家通常并不愿意安装一个久未使用、图标发灰的 App ,而是更倾向于直接打开浏览器获取信息,尽管 Web 的使用体验可能不如 App 那么好。

    那么,当我们手头有一个面向 C 端的产品时,应该如何选择平台呢?

    可选平台:

    • PC Web
    • 移动端 Web(手机、平板)
    • 移动端 App

    从产品规模和功能复杂度的角度来看:

    • 如果是一个功能复杂、逻辑重的大型产品,建议选择 App,因为它能更好地控制性能、交互体验与原生能力。
    • 如果是功能轻量、单一的工具型产品,使用 移动端 Web 会更加灵活、快捷,也更适合冷启动。

    从技术角度来说,移动端浏览器确实缺乏许多移动 App 的能力,主要原因包括以下几点:

    一、UI 与交互差异

    浏览器中的 HTML 元素无法与原生组件在交互与视觉体验上保持一致。例如,一些 UI 设计会提出“在移动端展示复杂表格”的需求,但实际上这违背了移动端轻交互的设计理念,体验通常很差。

    二、缺乏原生能力

    移动 Web 无法很好地支持原生 App 中的高级功能,如原生手势系统。Web 中的点击事件只是单一的响应,而原生中,用户手指的滑动、长按、按压等都由专门的系统处理,开发者只需关注逻辑即可。而在 Web 中实现这些,需要自己去监听 touch 事件、处理手势的 x/y 坐标、时间等,开发成本高,效果也不稳定。


    简单总结:

    移动端 Web 在 UI 和交互上难以与原生统一,不适合实现复杂交互,像“移动端上做复杂表格”这类设计在体验上本身就不合理。

    Web 应用缺乏原生能力支持,尤其在交互、手势、动画等方面难以还原原生体验。

    因此,平台的选择要基于产品复杂度、目标用户习惯、开发成本和迭代速度综合权衡。

    6 、结束

    欢迎加入群聊,我们一起讨论一些更有趣的技术、商业、闲聊。

    因为最近业务在写Rn,就正好巩固一下一些知识,也增强大伙的竞争力,后面估计这个部分会出很多章,想这种概念的东西还挺重要的,大伙可以吸收一下。

    6 条回复    2025-06-28 20:49:51 +08:00
    paranoiagu
        1
    paranoiagu  
       166 天前 via Android
    自持鸿蒙 next 吗?
    murmur
        2
    murmur  
       166 天前
    @paranoiagu https://gitee.com/openharmony-sig/ohos_react_native

    支持过但是最近仓库锁死,不知道啥情况
    NewYear
        3
    NewYear  
       165 天前
    @murmur #2

    鸿蒙这种搞法,感觉不大行得通。
    个人认为要别人适配,起码应该打钱吧。
    Jaosn
        4
    Jaosn  
       164 天前
    @NewYear 只要他出货量大,实体设备用户多,就轮到你求着来适配了,现在特别是跟 gov 强关联的
    pointup
        5
    pointup  
       136 天前
    个人建议选择 Flutter 吧或者原生来写 app 。(如果你需要面向国内用户使用的话)
    leia
      &nsp; 6
    leia  
    OP
       134 天前
    @pointup 可以的, 我目前也在这方面学习了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5391 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 07:15 PVG 15:15 LAX 23:15 JFK 02:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86