React as a UI Runtime(三、协调)

news/2024/11/9 18:00:11

1.协调

如果我们在同一个容器中使用两次ReactDOM.render()会发生什么?

ReactDOM.render(
  <button className="blue" />,
  document.getElementById('container')
);

// ... later ...

//  应该替换掉 button 宿主实例吗?
// 还是在已有的 button 上更新属性?
ReactDOM.render(
  <button className="red" />,
  document.getElementById('container')
);

再次说明,React的工作是使宿主树和提供的React元素的树一致。确定宿主树怎么样来响应新的信息的这个过程被称为协调。
协调有两种方法。React的简单的版本是抛弃已经存在的树,重新建立新的树:

let domContainer = document.getElementById('container');
// 清除树
domContainer.innerHTML = '';
// 创建新的宿主树
let domNode = document.createElement('button');
domNode.className = 'red';
domContainer.appendChild(domNode);

但是在DOM中,这是低效的,并且会丢失一些重要的信息像聚焦状态,选中状态,滚动状态等等。所以我们希望React像下面一样工作:

let domNode = domContainer.firstChild;
// Update existing host instance
domNode.className = 'red';

换句话说,React需要决定那时候需要更新一个已经存在的宿主实例来响应新的React元素,那时候需要新建一个宿主实例。
这就提出了关于分别的问题,React的元素可能一直在变化,那理论上那时候引用同一个宿主实例呢?
在我们的例子上是很简单的。我们已经创建了一个<button>作为第一个(也是唯一一个)子元素,并且我们希望在同一个地方再次渲染一个<button>。我们已经有一个<button>的宿主实例,我们就不需要再创建新的,再次使用它就好了。

这个已经与React的思想非常接近了。
如果元素的种类在树的同一个地方之前一次的渲染和接下来的渲染是相同的,React会再次使用已经存在的宿主实例。
下面是React带有备注的大致实现过程:

// let domNode = document.createElement('button');
// domNode.className = 'blue';
// domContainer.appendChild(domNode);
ReactDOM.render(
  <button className="blue" />,
  document.getElementById('container')
);

// 可以再次使用吗? Yes! (button → button)
// domNode.className = 'red';
ReactDOM.render(
  <button className="red" />,
  document.getElementById('container')
);

// 可以再次使用吗? No! (button → p)
// domContainer.removeChild(domNode);
// domNode = document.createElement('p');
// domNode.textContent = 'Hello';
// domContainer.appendChild(domNode);
ReactDOM.render(
  <p>Hello</p>,
  document.getElementById('container')
);

// 可以再次使用吗? Yes! (p → p)
// domNode.textContent = 'Goodbye';
ReactDOM.render(
  <p>Goodbye</p>,
  document.getElementById('container')
);

这套规则对子树也同样适用。例如,当我们在更新有两个<button>子组件时的<dialog>,React首先决定是否重用<dialog>
然后再对每一个子组件进行相同的过程。


http://www.niftyadmin.cn/n/3369351.html

相关文章

平衡二叉树——调整变换规则

平衡二叉树&#xff1a; 由来&#xff1a;为了解决二叉树在某些情况下形成链表。 特点&#xff1a;平衡因子小于2&#xff0c;进行平衡调整。 平衡因子&#xff1a;结点的左孩子&#xff0d;右孩子的绝对值。 平衡调整策略&#xff1a;LL型 LR型 RR型 RL型。 LL型调整规则…

【nginx】nginx的介绍

Nginx 反向代理初印象 Nginx (“engine x”) 是一个高性能的HTTP和反向代理 服务器&#xff0c;也是一个IMAP/POP3/SMTP服务器。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力确实在同类型的网页服务器中表现较好&#xff0c;中国大陆使用nginx网…

动态规划-使用最小花费爬楼梯为例

动态规划-使用最小花费爬楼梯为例 题目描述数组的每个下标作为一个阶梯&#xff0c;第 i 个阶梯对应着一个非负数的体力花费值 cost[i]&#xff08;下标从 0 开始&#xff09;。 每当你爬上一个阶梯你都要花费对应的体力值&#xff0c;一旦支付了相应的体力值&#xff0c;你就…

组合博弈知识汇总(算法)

原帖地址&#xff1a;http://www.wutianqi.com/?p1081以下是我从网上收集的关于组合博弈的资料汇总&#xff1a; 有一种很有意思的游戏&#xff0c;就是有物体若干堆&#xff0c;可以是火柴棍或是围棋子等等均可。两个人轮流从堆中取物体若干&#xff0c;规定最后取光物体者取…

Carla与Ros联合仿真教学与踩坑经历

Carla与Ros联合仿真教学与踩坑经历 前言 本人需要用到carla进行仿真&#xff0c;做实验&#xff0c;研究了这个平台几个月。 需要注意的是&#xff0c;本人没有保留所有的ros包&#xff0c;而是选择一些进行使用&#xff0c;其他大家可以进行扩展。 carla0.9.5版本和carla0.…

力扣-跳跃游戏Ⅱ

给你一个非负整数数组 nums &#xff0c;你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 假设你总是可以到达数组的最后一个位置。 public int jump(int[] nums) {int length nu…

八大排序——归并排序

归并排序&#xff08;Merge sort&#xff09; 定义 归并排序时建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。 作为一种典型的分而治之思想的算法应用&#xff0c;归并排序的实现有两种方法&#xff1a; 自上而下的递归&#xff08;所有…

WINCE驱动程序编写者指南(转载)

WINCE驱动程序编写者指南在CE中&#xff0c;最简单的一个驱动程序莫过于一个内置&#xff08;Built-in&#xff09;设备的流接口驱动。对于一个不支持热拔插的设备&#xff0c;最快捷的方法就是为其实现一个内置的流接口的驱动。对于这样一类驱动程序&#xff0c;我们只需要按一…