V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leia
V2EX  ›  前端开发

选择 React-native 的一些理由

  •  
  •   leia · 9 天前 · 835 次点击

    本文总结:

    🔹 运行机制 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,就正好巩固一下一些知识,也增强大伙的竞争力,后面估计这个部分会出很多章,想这种概念的东西还挺重要的,大伙可以吸收一下。

    4 条回复    2025-05-29 15:50:04 +08:00
    paranoiagu
        1
    paranoiagu  
       9 天前 via Android
    自持鸿蒙 next 吗?
    murmur
        2
    murmur  
       9 天前
    @paranoiagu https://gitee.com/openharmony-sig/ohos_react_native

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

    鸿蒙这种搞法,感觉不大行得通。
    个人认为要别人适配,起码应该打钱吧。
    Jaosn
        4
    Jaosn  
       8 天前
    @NewYear 只要他出货量大,实体设备用户多,就轮到你求着来适配了,现在特别是跟 gov 强关联的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2606 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:49 · PVG 19:49 · LAX 04:49 · JFK 07:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.