49

来自关于 Virtual DOM的 ReactJS wiki页面:

React 创建一个内存数据结构缓存,计算结果差异,然后有效地更新浏览器显示的 DOM。这允许程序员编写代码,就好像每次更改都会呈现整个页面,而 React 库只呈现实际更改的子组件。

换句话说,Virtual DOM 允许我们通过避免直接操作 DOM 来提高性能。

但是React Native呢?

我们知道,理论上在其他平台上存在原生视图和 UI 组件。DOM 本身并没有什么。那么我们可以说 React Native 有“虚拟 DOM”还是我们在谈论其他东西?

例如,Weex规范中有一描述了直接使用 DOM-tree 的方法。我的假设是,我们可能会认为 React Native 也应该有某种 DOM 树以及“虚拟 DOM”抽象层,这是 React 本身的主要思想。

所以我的问题是:

React Native 是否有某种“虚拟 DOM”(或其表示形式),如果有,如何将这种“虚拟 DOM”移植到各种平台?

更新:

这个问题的目的是阐明 React Native 如何管理原生 UI 组件的渲染。有没有具体的方法,如果有,它是如何正式命名的?

更新 2:

本文描述了名为Fiber的新 React 架构,它看起来像是这个问题的答案。

4

4 回答 4

45

简而言之

嗯.. 本质上,是的,就像 Reactjs 的 Virtual DOM 一样,React-Native 创建一个树层次结构来定义初始布局,并在每次布局更改时创建该树的差异以优化渲染。除了 React-Native 通过几个架构层管理 UI 更新之外,这些架构层最终会转换视图应该如何呈现,同时尝试将更改优化到最低限度,以提供尽可能快的呈现。

更详细的解释

为了了解 react native 如何在后台创建视图,您需要了解基础知识,为此,我宁愿从头开始

1.Yoga布局引擎

Yoga是一个用 C 语言编写的跨平台布局引擎,它通过绑定到本机视图(Java Android Views / Objective-C iOS UIKit)来实现 Flexbox 。

React-Native 中各种视图、文本和图像的所有布局计算都是通过瑜伽完成的,这基本上是我们的视图显示在屏幕上之前的最后一步

2.阴影树/阴影节点

当 react-native 发送命令来渲染布局时,一组影子节点被组装起来构建影子树,它代表了布局的可变原生端(即:用相应的原生语言编写,Java for Android 和 Objective-C对于 iOS),然后将其转换为屏幕上的实际视图(使用 Yoga)。

3. 视图管理器

ViewManger 是一个接口,它知道如何将从 JavaScript 发送的视图类型转换为它们的本机 UI 组件。ViewManager 知道如何创建影子节点、本地视图节点和更新视图。在 React-Native 框架中,有很多 ViewManager 可以使用原生组件。例如,如果有一天您想创建一个新的自定义视图并将其添加到 react-native,则该视图必须实现 ViewManager 接口

4. 用户界面管理器

UIManager 是拼图的最后一块,或者实际上是第一块。JavaScript JSX 声明式命令作为命令式命令发送到本机,告诉 React-Native 如何布局视图,逐步迭代。因此,作为第一次渲染,UIManager 将调度命令以创建必要的视图,并将随着应用程序的 UI 随时间的变化而继续发送更新差异。

所以 React-Native 基本上还是利用了 Reactjs 的能力来计算之前和当前的渲染表示之间的差异,并据此将事件分派给 UIManager

要更深入地了解该过程,我推荐Emil Sjölander在弗罗茨瓦夫举行的 React-Native EU 2017 会议上的以下演讲

于 2018-02-21T22:58:07.857 回答
5

我不知道这是否是您问题的答案,但我在官方 React 文档中找到了这个:

React 构建并维护渲染 UI 的内部表示。它包括您从组件返回的 React 元素。这种表示可以让 React 避免创建 DOM 节点和不必要地访问现有节点,因为这可能比对 JavaScript 对象的操作要慢。有时它被称为“虚拟 DOM”,但它在 React Native 上的工作方式相同。

所以我会说是的,它管理的内部表示与 React.js 中使用的表示非常相似。然后我猜它使用 Javascript API 来呈现原生视图,就像您阅读的文章所建议的那样。

编辑 Sebas在评论中提供的这篇文章也很有趣,因为 React(和 React Native)团队的成员说:

React Native 表明,ReactJS 一直以来更多的是关于“零 DOM”而不是“虚拟 DOM”(与流行的看法相反)。

看起来所谓的“React 虚拟 DOM”更接近于可以映射到各种技术的元素的内部结构/表示,而不是 HTML DOM。

于 2017-01-23T14:23:59.770 回答
3

本文描述了名为Fiber的新 React 架构。这似乎是关于 React Native 中正在发生的事情的正确答案,或者至少是 React Native 将在最近的将来尝试实现的目标。

DOM 只是 React 可以渲染的渲染环境之一,其他主要目标是通过 React Native 实现的原生 iOS 和 Android 视图。(这就是为什么“虚拟 DOM”有点用词不当。)

它可以支持这么多目标的原因是因为 React 的设计使得协调和渲染是独立的阶段。协调器负责计算树的哪些部分发生了变化;渲染器然后使用该信息来实际更新渲染的应用程序。

这种分离意味着 React DOM 和 React Native 可以使用自己的渲染器,同时共享由 React 核心提供的同一个协调器。

Fiber 重新实现了协调器。

于 2017-03-27T06:17:04.373 回答
1

这是一个过度简化:ReactJS 输出可以呈现给浏览器的 DOM。如您所知,虚拟 DOM 帮助 ReactJS 有效地跟踪变化的增量。对于 iOS 的 React Native,最终它会输出 UIKit 代码。与 React Native for Android 相同,但不是输出 DOM 或 UI Kit,而是使用 Android SDK 创建输出。所以虚拟 DOM 只是一个中间步骤。它可以被认为是内部数据结构的组合,用于保存描述在何处呈现按钮和文本框的数据,当您单击按钮时会发生什么等,以及跟踪更改的有效算法。相同的代码可用于所有平台。只有最后一步不同。根据平台的不同,它有生成 DOM 的代码、UIKit 代码、

于 2017-01-23T14:50:59.247 回答