我试图更牢固地了解一些React内部。我了解到,React的工作原理如下:
我的问题是关于刚才描述的过程的详细信息(希望正确):
对帐过程是否总是从应用程序根目录开始 (即,将旧的虚拟DOM与新的虚拟DOM从两棵树的顶部开始进行比较),还是只知道以某种方式知道diff重新渲染了组件?
为了更清楚地说明我所追求的目标,请考虑以下示例。假设我的应用程序是这样的结构:
<main id="app">
<section id="part1">...</section>
<section id="part2">...</section>
</main>
让我们假设只有“ part1”组件已被重新渲染。现在,和解开始。调节算法是只比较“ part1”,还是从主要应用程序组件开始,遍历整棵树(包括“ part2”)?
This question与我的非常相似,但是被接受的答案是关于重新渲染而不是差异,因此它并不能明确回答我的问题。
答案 0 :(得分:0)
对帐过程是否始终从应用程序根目录开始
不,那不可能。 “新的虚拟DOM”是从render()
调用(或从调用功能组件)返回的内容,而Component仅在状态改变时才重新渲染。因此,由于更新后的元素只有一个“新的虚拟DOM”,因此只能在这些元素上进行协调(有意义的是仅执行必要的工作)。
一些伪代码:
const dom = {
props: {},
type: App,
el: document.getElementById("app"),
children: [{
type: Child,
props: {},
children: [],
}],
};
function reconcile(domNode, update) {
for(const [i, child] of domNode.children.entries()) {
// If nothing changed, skip
if(child.type === update[i].type && child.props === update[i].props)
continue;
// Replace the child
if(child.type !== update[i].type) {
removeDomNode(child.el);
addDomNode(update[i]);
Object.assign(child, update[i]);
reconcile(child.children, update[i].children); // go on recutsively
}
//...
}
}
// Rerender the first Child
reconcile(dom.children[0], Child());