宿主树

大多数教程把 React 称作是一个 UI 库。这是有道理的,因为 React 就是一个 UI 库。正如官网上的标语所说的那样—构建用户界面的库。

但是本篇文章将以一种不同的方式来讲述 React — 因为它更像是一种编程运行时。

本篇文章不会教你任何有关如何创建用户界面的技巧。但是它可能会帮助你更深入地理解

React 编程模型。

React 程序通常会输出一棵会随时间变化的树。有可能是一棵 DOM 树 ,iOS 视图层 ,又或是 JSON 对象 通常我们希望用它来展示 UI 。我们称它为“宿主树”

所以到底 React 有什么用呢?非常抽象地,它可以帮助你编写可预测的,并且能够操控复杂的宿主树进而响应像用户交互、网络响应、定时器等外部事件的应用程序。

稳定性。宿主树是相对稳定的,大多数情况的更新并不会从根本上改变其整体结构。如果应用程序每秒都会将其所有可交互的元素重新排列为完全不同的组合,那将会变得难以使用。比如按钮突然不见了?

通用性。宿主树可以被拆分为外观和行为一致的 UI 模式(例如按钮、列表和头像)而不是随机的形状。

宿主实例

宿主树由节点组成,我们称之为“宿主实例”。

在 DOM 环境中,宿主实例就是我们通常所说的 DOM 节点 — 就像当你调用 document.createElement('div') 时获得的对象。在 iOS 中,宿主实例可以是从 JavaScript 到原生视图唯一标识的值。

宿主实例有它们自己的属性(例如 domNode.className 或者 view.tintColor )。它们也有可能将其他的宿主实例作为子项。

通常会有原生的 API 用于操控这些宿主实例。例如,在 DOM 环境中会提供像 appendChildremoveChildsetAttribute 等一系列的 API 。

渲染器

渲染器教会 React 如何与特定的宿主环境通信以及如何管理它的宿主实例。React DOM、React Native 都可以称作 React 渲染器。

React 渲染器能以下面两种模式之一进行工作。

绝大多数渲染器都被用作“突变”模式。这种模式正是 DOM 的工作方式:我们可以创建一个节点,设置它的属性,在之后往里面增加或者删除子节点。宿主实例是完全可变的。

但 React 也能以“不变”模式工作。这种模式适用于那些并不提供像 appendChild 的 API 而是克隆双亲树并始终替换掉顶级子树的宿主环境。在宿主树级别上的不可变性使得多线程变得更加容易。React Fabric 就利用了这一模式。

作为 React 的使用者,你永远不需要考虑这些模式。我只想强调 React 不仅仅只是从一种模式转换到另一种模式的适配器。它的用处在于以一种更好的方式操控宿主实例而不用在意那些低级视图 API 范例。

React 元素

在宿主环境中,一个宿主实例(例如 DOM 节点)是最小的构建单元。而在 React 中,最小的构建单元是 React 元素。

React 元素是一个普通的 JavaScript 对象。它用来描述一个宿主实例。

// JSX 是用来描述这些对象的语法糖。
// <button className="blue" />
{type: 'button',props: { className: 'blue' }
}

React 元素是轻量级的因为没有宿主实例与它绑定在一起。同样的,它只是对你想要在屏幕上看到的内容的描述。

但是,请记住 React 元素并不是永远存在的 。它们总是在重建和删除之间不断循环着。

React 元素具有不可变性。例如,你不能改变 React 元素中的子元素或者属性。如果你想要在稍后渲染一些不同的东西,你需要从头创建新的 React 元素树来描述它。

我喜欢将 React 元素比作电影中放映的每一帧。它们捕捉 UI 在特定的时间点应该是什么样子。它们永远不会再改变。

入口

每一个 React 渲染器都有一个“入口”。正是那个特定的 API 让我们告诉 React ,将特定的 React 元素树渲染到真正的宿主实例中去。

例如,React DOM 的入口就是 ReactDOM.render :

ReactDOM.render(// { type: 'button', props: { className: 'blue' } }<button className="blue" />,document.getElementById('container')
);

当我们调用 ReactDOM.render(reactElement, domContainer) 时,我们的意思是:“将我的 reactElement 映射到 domContaienr 的宿主树上去吧。”

React 会查看 reactElement.type (在我们的例子中是 button )然后告诉 React DOM 渲染器创建对应的宿主实例并设置正确的属性:

// 在 ReactDOM 渲染器内部(简化版)
function createHostInstance(reactElement) {let domNode = document.createElement(reactElement.type);domNode.className = reactElement.props.className;return domNode;
}

在我们的例子中,React 会这样做:

let domNode = document.createElement('button');
domNode.className = 'blue';domContainer.appendChild(domNode);

如果 React 元素在 reactElement.props.children 中含有子元素,React 会在第一次渲染中递归地为它们创建宿主实例。

将 React 作为 UI 运行时相关推荐

  1. android异步线程未执行,关于多线程:当服务在后台运行时,Android异步任务无法正常运行(doInBackground未执行)...

    我注意到有时Async任务无法正常运行,实际上它的doInBackground()方法没有被调用,这种情况主要发生在该活动在后台运行任何服务时. 例如,当音乐在带有服务的后台运行时,Async任务不会 ...

  2. 云原生应用程序运行时 Kyma 的主要特性介绍

    Kyma 是一个应用程序运行时,提供了一种在 Kubernetes 的云原生世界中连接.扩展和自定义应用程序的灵活且简单的方法. Kyma 开箱即用,提供各种功能,例如: 以经济高效和可扩展的方式运行 ...

  3. webpack联邦模块之webpack运行时

    webpack是如何打包ES模块的?webpack是如何构建自身的模块运行时的? __webpack_require__ 这是整个webpack运行时的核心. 该函数被用于根据模块Id从变量__web ...

  4. Frida Hook Android App 进阶用法之 Java 运行时

    FridaHookAndroid 本文旨在覆盖使用 Frida 对 Android App 进行 hook 的绝大多数场景.文章提到的所有代码以及被测 App,详见:https://github.co ...

  5. 【小睿精选·第四期】谷歌开源更快、更高效的 TensorFlow 运行时 TFRT

    [小睿精选] [小睿精选]第四弹来啦,本期共收录6条嵌入式资讯信息,希望可以帮到你.欢迎大家在文末留言,唠一唠你关注的话题,说不定下期就有你想要的惊喜! 1.中科蓝讯与阿里"平头哥" ...

  6. Windows Java JavaFX IntelliJ IDEA 开发环境搭建 创建工程 编译运行 打包分发 自定义运行时

    博文目录 文章目录 本文说明 JavaFX 简单说明 JavaFX 版本说明 JavaFX 与 JDK 的关系 JavaFX 与 JDK Modular (JDK 9 模块化系统) JavaFX 模块 ...

  7. ART运行时Foreground GC和Background GC切换过程分析

    通过前面一系列文章的学习,我们知道了ART运行时既支持Mark-Sweep GC,又支持Compacting GC.其中,Mark-Sweep GC执行效率更高,但是存在内存碎片问题:而Compact ...

  8. Go 运行时(go runtime)的含义

    go 运行时,也称为 go runtime.其本身就是每个 go 程序的一部分,它会跟你的源码一起编译并连接到目标程序中.即便你只是写了一个 hello world 程序,这个程序中也包含了 runt ...

  9. Deep Learning部署TVM Golang运行时Runtime

    Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...

最新文章

  1. 特征变换(3)小波变换
  2. 《转》四本与携程相关的书
  3. 将旧项目从Ant迁移到Maven的4个简单步骤
  4. redhat linux7.0的安装
  5. oracle 对应的JDBC驱动 版本
  6. python request url编码_Python 爬虫 (requests) 发送中文编码的 HTTP POST 请求
  7. Net Framework 4.0 和.Net Framework 4.0 Client Profile
  8. Spring框架----Spring常用IOC注解的分类
  9. nginx windows启动停止_Nginx之3抛砖引玉 - (目录索引)
  10. Android MediaPlayer的生命周期
  11. Service服务学习(SimpleRandomServiceDemo)
  12. UI设计工作流程步骤详解,让你快速了解UI设计!
  13. 关于awk 中如何使用 if条件判断句
  14. ms office word2013教程 - 文字处理之插入复合条饼图
  15. 姚舜:成年人的崩溃,“我只是想哭一下”
  16. 写代码有这16个好习惯,可以减少80%非业务的bug
  17. C语言程序设计笔记(浙大翁恺版) 第九周:指针
  18. Android项目必备技术
  19. c++ 工具库 (zz)
  20. 一键百度 一键翻译 云脉CC慧眼百度搜索版

热门文章

  1. 几行代码起家到实时音视频一线,6 岁声网计划赴美上市!
  2. 我肝了一个月,给你写出了这本 Java 开发手册!
  3. 无人机小区上空盘一圈测体温,背后技术靠谱吗?
  4. 马云再谈对钱没有兴趣;比尔·盖茨:微软原本可以击败 Android!TypeScript 3.7 发布 | 极客头条...
  5. CSRankings 学术机构排行榜:“三巨头”不可撼动,清华大学突围 AI 榜单!
  6. 2019 年互联网人才招聘报告:Java 吃香,算法工程师紧缺,今日头条崛起!
  7. 为什么雷军指责“华为不懂研发”?| 畅言
  8. 凉凉了,Eureka 宣布闭源,Spring Cloud 何去何从?
  9. 携程否认竞价排名;戴尔为“吃鸡外挂”致歉;腾讯将发区块链游戏 | CSDN极客头条
  10. 那个说技术本身并不可耻的快播王欣回来了!