React对帐算法的切入点是什么?

时间:2019-08-21 10:06:12

标签: javascript reactjs

我试图更牢固地了解一些React内部。我了解到,React的工作原理如下:

  • 它将仅重新渲染已更改的组件。
  • 然后,它将“旧的”虚拟DOM(在重新渲染之前)与“新的”虚拟DOM(在重新渲染之后)进行比较,并修补真实的DOM以解决更改。

我的问题是关于刚才描述的过程的详细信息(希望正确):

对帐过程是否总是从应用程序根目录开始 (即,将旧的虚拟DOM与新的虚拟DOM从两棵树的顶部开始进行比较),还是只知道以某种方式知道diff重新渲染了组件?

为了更清楚地说明我所追求的目标,请考虑以下示例。假设我的应用程序是这样的结构:

<main id="app">
  <section id="part1">...</section>
  <section id="part2">...</section>
</main>

让我们假设只有“ part1”组件已被重新渲染。现在,和解开始。调节算法是只比较“ part1”,还是从主要应用程序组件开始,遍历整棵树(包括“ part2”)?

This question与我的非常相似,但是被接受的答案是关于重新渲染而不是差异,因此它并不能明确回答我的问题。

1 个答案:

答案 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());