请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

appendAllChildren 和 finalizeInitialChildren 是否有重复的功能

老师您好,上述两个方法中,都存在对于文本子节点的处理,

appendAllChildren 中通过 appendInitialChild 将文本节点添加 DOM 中,

finalizeInitialChildren 中通过对 props.children 的处理,也会将文本节点添加到 DOM,

这两处的操作是重复的嘛?

正在回答

1回答


这个问题问得很好很深入,要回答好这个问题需要对Fiber树的构建过程有很清晰的认知。

确实这两个地方都会处理文本节点,但是这两个处理的是不同的文本节点,所以不存在重复。当一个节点有多个子节点的时候,在执行函数appendAllChildren时会把所有的子节点添加到父dom上,但这样处理的前提是,该文本节点有对应的Fiber对象,因为这里找所有子节点的依据是根据fiber对象来的。然而,由于React内部做了优化,当一个节点只有单个子节点,而且该子节点是文本节点,那么就不会为该文本节点创建fiber对象。具体代码体现在ReactFiberBeginWork文件中的函数:

unction updateHostComponent(current, workInProgress) {
  const { type } = workInProgress;
  const nextProps = workInProgress.pendingProps;
  let nextChildren = nextProps.children;
  const isDirectTextChild = shouldSetTextContent(type, nextProps);
  if (isDirectTextChild) {
    nextChildren = null;
  }
  reconcileChildren(current, workInProgress, nextChildren);
  return workInProgress.child;
}

这段代码中有一个条件判断,如果是直接的文本节点,nextChidren设置为null,而当nextChildren为null ,reconcileChildren执行完后,workInProgress.child为null,也就是该文本节点没有对应的Fiber对象。所以在函数finalizeInitialChildren中通过对props.children的形式进行了处理。

可以用这样一个例子来调试观察:

<div>
    text1
    <span>
        text2
    </span>
</div>

你会发现text1和text2的处理时机是不一样的,这也就能很好说明为什么appendAllChildren和finalizeInitialChildren不存在重复处理文本节点的问题。

2 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号