Preact: Hello, what is the function of the _lastDomChild attribute?

Created on 27 Mar 2019  路  1Comment  路  Source: preactjs/preact

diff.js

In the file diff.js, the _lastDomChild is given newVNode._children[newVNode._children.length - 1]._dom

if (oldVNode.type === Fragment || newType === Fragment) {
    diffChildren(parentDom, newVNode, oldVNode, context, isSvg, excessDomChildren, mounts, c);

    if (newVNode._children.length) {
        dom = newVNode._children[0]._dom;
        newVNode._lastDomChild = newVNode._children[newVNode._children.length - 1]._dom;
    }
}

diffchildren.js

It doesn't seem to be used

if (childVNode._lastDomChild != null) {

    newDom = childVNode._lastDomChild;
}
else if (excessDomChildren == oldVNode || newDom != childDom || newDom.parentNode == null) {
  // .... 
}

I am learning the source code of preact锛宼hank you

Most helpful comment

That's a great question! The property _lastDomChild is used for Fragments. Each vnode has a _dom property which denotes the first child node of a given vnode. With Fragments there will be a different relationship between the DOM and a vnode.

That 1:1 mapping doesn't hold true for them anymore and we chose _lastDomChild as a pointer to the last child node of a vnode. This becomes more important when there are nested or sibling Fragments at play. In these cases we need to be very aware of our current position to modify the DOM at the correct place.

// Sibling Fragments
<div>
  <Fragment>foo</Fragment>
  <Fragment>bar</Fragment>
  <span>bob</span>
</div>

// Nested Fragments
<div>
  <Fragment>
    <Fragment>
      <div>foo</div>
    </Fragment>
  </Fragment>
</div>

Typically there are lots of cases in real world apps where both scenarios are used together. That said, our current reconciler (what's in diffChildren()) needs to be switched to diff based on the index in the children array instead of getting the correct child by traversing the DOM. In current code where checking for newDom in the line you posted above and use it to compare the current childDom against it.

We believe that this is necessary to fix the remaining issues with Fragments. It's something on our todo list and that we have a few branches where we experimented with, but we're waiting for #1440 to be merged to tackle it.

Besides the JSDoc comments we have a few hints in our internal typings (usually internal.d.ts) about the use of each property.

Hope this helps to get you started :)

>All comments

That's a great question! The property _lastDomChild is used for Fragments. Each vnode has a _dom property which denotes the first child node of a given vnode. With Fragments there will be a different relationship between the DOM and a vnode.

That 1:1 mapping doesn't hold true for them anymore and we chose _lastDomChild as a pointer to the last child node of a vnode. This becomes more important when there are nested or sibling Fragments at play. In these cases we need to be very aware of our current position to modify the DOM at the correct place.

// Sibling Fragments
<div>
  <Fragment>foo</Fragment>
  <Fragment>bar</Fragment>
  <span>bob</span>
</div>

// Nested Fragments
<div>
  <Fragment>
    <Fragment>
      <div>foo</div>
    </Fragment>
  </Fragment>
</div>

Typically there are lots of cases in real world apps where both scenarios are used together. That said, our current reconciler (what's in diffChildren()) needs to be switched to diff based on the index in the children array instead of getting the correct child by traversing the DOM. In current code where checking for newDom in the line you posted above and use it to compare the current childDom against it.

We believe that this is necessary to fix the remaining issues with Fragments. It's something on our todo list and that we have a few branches where we experimented with, but we're waiting for #1440 to be merged to tackle it.

Besides the JSDoc comments we have a few hints in our internal typings (usually internal.d.ts) about the use of each property.

Hope this helps to get you started :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jasongerbes picture jasongerbes  路  3Comments

youngwind picture youngwind  路  3Comments

paulkatich picture paulkatich  路  3Comments

Zashy picture Zashy  路  3Comments

simonjoom picture simonjoom  路  3Comments