React as a UI Runtime(三、协调)

news/2024/5/18 20:38:18

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>
然后再对每一个子组件进行相同的过程。


https://dhexx.cn/news/show-2960711.html

相关文章

调用微信的接口报错errcode: 40164 invalid ip

调用微信的接口报错errcode: 40164 调用微信的接口报错 { errcode: 40164, errmsg: invalid ip 117.100.47.169 ipv6 ::ffff:117.100.47.169, not in whitelist hint: [39lrcA01394100] } 报这个错是说&#xff0c;调用微信的接口的ip地址不在白名单内。 解决办法&#xff1…

Python图像处理(14):神经网络分类器

快乐虾http://blog.csdn.net/lights_joy/欢迎转载&#xff0c;但请保留作者信息在opencv中支持神经网络分类器。本文尝试在python中调用它。和前面的贝叶斯分类器一样。神经网络也遵循先训练再使用的方式&#xff0c;我们直接在贝叶斯分类器的測试代码上做简单改动&#xff0c;…

vue + canvas 截取视频的预览图

在页面中加载太多的视频&#xff0c;会造成页面加载慢&#xff0c;所以在显示视频的地方显示视频的预览图。用vue 和 canvas 截取视频的预览图。 示例图&#xff1a; demo: <template> <div id"demo"><div class"video-wrapper" :stylevi…

webstorm使用技巧

在Webstorm中使用正则进行查找或替换 使用正则来查找http://stackoverflow.com/ques... 想该行数据替换为下行数据。include border-radius($big-radius); border-radius: $big-radius;Search for: 在搜素框中日填写下行。 include(.*)\((.*)\); Replace with: 在替换框中填写下…

如何在元素内容前后加图标

大家最常用作图标的元素是i标签&#xff0c;为什么呢&#xff1f; 用 <i> 元素做图标在语义上是不正确的&#xff08;虽然看起来像 icon 的缩写&#xff09;&#xff1b;<i> 比 <span> 短&#xff0c;但 gzip 后差异很小&#xff0c;不过打字可以少按三个键&…

2017.04.19 有趣的机械原理图

作为机械工程师&#xff0c;你见识的巧妙结构、机构越多&#xff0c;设计思路也就越开阔。齿轮、梁板、凸轮、滑轨……看似简单的零部件&#xff0c;被天才工程师巧妙地组合到一起&#xff0c;就能精确完成各类复杂的工作。 ▲这张就够你看一年了 ▲100多年前&#xff0c;古老自…

recovery的一些开发点滴

Android的recovery是我在公司做的最多的&#xff0c;应该也是我在Android中了解的较为深入的一个部分。recovery这部分其实Android本身都已经提供了很完善的一套机制&#xff0c;但是因为公司是做机顶盒的&#xff0c;所以在因为平台订制的关系&#xff0c;recovery这部分还是做…

感谢CSDN赠送的图书和杂志(5月份)

互联网的精神就是开放。就是分享。在分享的同一时候。我们也会收获到意外的回报。近期。因为我在5月份发表了14篇博文&#xff0c;因此CSDN赠送了一本图书《软件系统架构》(本人自己选的)和一本《程序猿》杂志。截图例如以下&#xff1a;本人5月份发表的全部博文參见&#xff1…

协同OA产品要完全符合企业的办公模式吗?

当前&#xff0c;协同OA系统已从简单的工作流程变成为了一个企业运营管控平台和信息化的集成平台&#xff0c;更是通过移动化已经融入到每一个员工的日常工作中了&#xff0c;OA系统已然成为新时期助力企业发展的“神器”。所以&#xff0c;很多企业在选择协同OA产品时尤为谨慎…

java 多线程--------(一)

创建线程的4种方式 1、继承Thread类&#xff0c;复写run方法&#xff0c;run方法中为线程需要执行的逻辑部分&#xff0c;而启动线程调用start方法。小示例见代码&#xff0c;通过Thread.currentThread().getName()可以获得当前线程名称 public class MyThread extends Thread …