iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >一文掌握React 组件树遍历技巧
  • 131
分享到

一文掌握React 组件树遍历技巧

React 组件树遍历React 组件遍历 2023-05-16 11:05:17 131人浏览 安东尼
摘要

目录引言React 内部遍历核心逻辑:所以对于这段 dom 的遍历逻辑是:总结遍历逻辑如下图所示引言 本文对应的 react 版本是 18.2.0 下面的 dom 结构react

引言

本文对应的 react 版本是 18.2.0

下面的 dom 结构react 内部是如何遍历的

const App = () => {
  return (
    <div>
      <button>+1</button>
      <A count={0} />
    </div>
  );
};
const A = (props) => {
  useEffect(() => {
    console.log(props.count);
  }, [props.count]);
  return <div>{props.count}</div>;
};

react 内部遍历核心逻辑:

  • render 时调用 commitPassiveUnmountOnFiber 函数
  • commitPassiveUnmountOnFiber 处理不同的 WorkTag,并调用 recursivelyTraversePassiveUnmountEffects
  • recursivelyTraversePassiveUnmountEffects 根据当前 Fiber 的子节点有没有 passive effectuseEffectuseLayoutEffect)来决定是否遍历当前 Fiber 的子节点
    • 如果子节点有 passive effect,则优先遍历子节点 (深度优先),直到找到最终的叶子节点,退出当前循环
    • 然后进入兄弟节点,开始遍历兄弟节点的子节点
      • 具体从哪个兄弟节点开始遍历,react 选择的是离退出循环的那个叶子节点的父节点,检查有没有子节点,以此循环遍历
    • 直到最后找到所有有 passive effect 的节点

代码简化:

commitPassiveUnmountOnFiber(root.current);
function commitPassiveUnmountOnFiber(finishedWork) {
  // 省略了处理不同的 WorkTag
  recursivelyTraversePassiveUnmountEffects(finishedWork);
}
function recursivelyTraversePassiveUnmountEffects(parentFiber) {
  // 省略了其他处理
  if (parentFiber.subtreeFlags & PassiveMask) {
    let child = parentFiber.child;
    while (child !== null) {
      commitPassiveUnmountOnFiber(child);
      child = child.sibling;
    }
  }
}

所以对于这段 dom 的遍历逻辑是:

  • 首先从根组件开始 FiberRootnode,取到 current
    • 也就是说 FiberRootNode.currentdiv#root 这是一个 fiber,它的 tag3
  • 由于 App 的子组件有 passive effect,所以会进入 App 组件,它的 tag0
  • App 组件中节点是 <div><di >tag5
    • <div> 下面有两个子元素 <button><A>
  • 先遍历 <button> 它的 tag5
  • <button> 内部只有一个文本节点,没有 passive effect
    • 所以 react 不遍历了(跳出当前遍历的循环,也就是 button 这条不在遍历了)
  • 跳出循环后,查看 button 的兄弟节点,它的兄弟节点是 <A><A>tag0
  • 由于 <A> 节点的子节点没有 passive effect,所以跳出循环,结束整个遍历

总结

  • 从跟节点开始遍历
  • 当前组件的子组件有没有 passive effect
  • 采取深度优先
  • 如果 dom 节点内有函数组件,则这个 dom 会被遍历,否则不会遍历
  • 如果当前 fiber 下的所有子 fiber 都没有 passive effect ,则这一整个都链表都不会被遍历
  • 如果当前 fiber 只有 dom,则这些 dom 也不会遍历

总的来说组件会不会别遍历看 fiber 有没有 passive effect

  • 有,一定会被遍历
  • 没有,下面两种情况会被遍历,其他情况不会被遍历
    • passive effect 的父组件
    • passive effect 组件是兄弟组件

passive effect 指的是 useEffectuseLayoutEffect

遍历逻辑如下图所示

图中画绿色勾的都会被遍历,红色勾是遍历的顺序

以上就是一文掌握React 组件树遍历技巧的详细内容,更多关于React 组件树遍历的资料请关注编程网其它相关文章!

--结束END--

本文标题: 一文掌握React 组件树遍历技巧

本文链接: https://www.lsjlt.com/news/209688.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作