采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
老师您好,上述两个方法中,都存在对于文本子节点的处理,
appendAllChildren 中通过 appendInitialChild 将文本节点添加 DOM 中,
finalizeInitialChildren 中通过对 props.children 的处理,也会将文本节点添加到 DOM,
这两处的操作是重复的嘛?
这个问题问得很好很深入,要回答好这个问题需要对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不存在重复处理文本节点的问题。
登录后可查看更多问答,登录/注册
通过手写5000+,深入理解 React 内部机制
701 9
413 7
687 7
789 6
614 5
购课补贴联系客服咨询优惠详情
慕课网APP您的移动学习伙伴
扫描二维码关注慕课网微信公众号