React Fiber框架中的Commit提交阶段——commitMutationEffect函数

news2025/1/13 20:30:24

Render阶段

Render阶段可大致归为beginWork(递)和completeWork(归)两个阶段

1.beginWork流程(递)

  1. 建立节点的父子以及兄弟节点关联关系
    child return sibling属性
  2. 给fiber节点打上flag标记(当前节点的flag)
    渲染阶段结束fiberRootNode.finishwork=wip,进入就断除

2.completeWork流程(归)
主要执行任务:
1.创建真实dom节点,但是仍在内存中,未渲染到页面
2.处理flag与subtreeFlags标记子树标识,用“|” 位运算处理)
3.建立真实DOM关系,将子元素插入父元素中
completeWork归工作完成,将建立fiberRootNode.finishWork=wip关系,当然进入

Commit阶段

  1. commit工作前又会断掉此关系。(状态机,标识运行状态)
  2. 当commitMutationEffect(commit执行完),将dom渲染到页面中之后
    root.current=finishedWork断开和老节点的联系指向新节点

在这里插入图片描述
在这里插入图片描述

function commitRoot(root:FiberRootNode){
	const finishedwork =root.finishedwork;
	if(finishedwork === null){
		return;
	}
	console.log('commit阶段开始',finishedwork);
	root.finishedwork=null;
	//判断是否存在3个子阶段需要执行的造作
	// root flags root subtreerlags
	const subtreeHaseffect=
	(finishedwork.subtreeFlags & MutationMask)!== NoFlags;
	const rootHasEffect:(finishedwork,flags & MutationMask) !== NoFlags;
	if(subtreeHasEffectrootHasEffect){
		// beforeMutation
		//mutation placement
		commitMutationEffects(finishedwork);
		root.current =finishedwork;
		// layout
	}else {
		root.current =finishedwork;
	}

在这里插入图片描述

  • 在渲染阶段的completeWork函数中已经构建真实DOM的关系,并对fiber树的每个节点进行了标识。标识包括两部分,一个是flag标识当前节点是否有DOM副作用操作,另一个就是subtreeFlag标识当前节点的子树是否有DOM副作用操作
  • 巧妙的双flag,后续更改,虚拟DOM跟着有关?
    在这里插入图片描述

commitMutationEffects函数详解

在React的Fiber架构中,commitMutationEffects是一个内部函数,负责在“commit”阶段的“mutation”子阶段中执行DOM更新。这个函数是React渲染流程中的关键一环,它确保了React组件的状态变更能够正确地反映到真实的DOM结构上。

function commitMutationEffects(root, finishedWork, committedLanes) {
  let nextEffect = finishedWork;

  // 遍历 Fiber 树,处理副作用
  while (nextEffect !== null) {
    const deletions = nextEffect.deletions;
    if (deletions !== null) {
      for (let i = 0; i < deletions.length; i++) {
        const childToDelete = deletions[i];
        commitDeletion(root, childToDelete);
      }
    }

    if (nextEffect.subtreeFlags & MutationMask) {
      const child = nextEffect.child;
      if (child !== null) {
        child.return = nextEffect;
        nextEffect = child;
        continue;
      }
    }
    commitMutationEffectsOnFiber(nextEffect, root, committedLanes);

    const sibling = nextEffect.sibling;
    if (sibling !== null) {
      sibling.return = nextEffect.return;
      nextEffect = sibling;
      continue;
    }

    nextEffect = nextEffect.return;
  }
}

function commitMutationEffectsOnFiber(finishedWork, root, committedLanes) {
  const flags = finishedWork.flags;

  // 插入新节点
  if (flags & Placement) {
    commitPlacement(finishedWork);
    finishedWork.flags &= ~Placement; // 清除 Placement 标记
  }

  // 更新节点
  if (flags & Update) {
    commitUpdate(finishedWork);
  }

  // 删除节点
  if (flags & Deletion) {
    commitDeletion(root, finishedWork);
  }

  // 处理 refs
  if (flags & Ref) {
    commitAttachRef(finishedWork);
  }
}
function commitPlacement(finishedWork) {
  const parentFiber = getHostParentFiber(finishedWork);
  const parent = getHostParent(parentFiber);

  if (parent !== null) {
    const before = getHostSibling(finishedWork);
    appendChildToContainer(parent, finishedWork.stateNode, before);
  }
}

function commitDeletion(root, childToDelete) {
  // 清理 refs
  if (childToDelete.flags & Ref) {
    commitDetachRef(childToDelete);
  }

  // 卸载子组件
  unmountHostComponents(childToDelete);

  // 如果节点有副作用清理函数,执行它们
  const alternate = childToDelete.alternate;
  if (alternate !== null) {
    const finishedEffect = alternate.lastEffect;
    if (finishedEffect !== null) {
      // 执行 Effect 的销毁函数
      commitPassiveUnmountEffects(finishedEffect);
    }
  }
}

commitMutationEffects的作用

commitMutationEffects的主要任务是遍历Fiber树中的effect list(副作用列表),并执行与DOM操作相关的副作用。这些副作用可能包括:

  • 插入新元素:当React组件被添加到DOM中时,需要创建新的DOM节点并将其插入到正确的位置。
  • 删除旧元素:当React组件被移除时,需要从DOM中删除对应的节点。
  • 更新元素属性:当React组件的属性(props)或状态(state)发生变化时,需要更新DOM节点的属性以反映这些变化。
  • 文本内容更新:对于文本节点,当文本内容发生变化时,需要更新DOM节点的文本内容。

执行过程

在执行commitMutationEffects时,React会按照Fiber树的遍历顺序,逐个处理effect list中的每个effect。对于每个effect,React会根据其类型(如插入、删除、更新等)执行相应的DOM操作。

  • 遍历 Fiber 树
    React 使用深度优先的方式遍历 Fiber 树,对每一个 Fiber 节点检查是否有需要执行的副作用(Effect)。
  • 处理不同的副作用标记
    每个 Fiber 节点有一个 flags 属性,表示需要处理的副作用类型。在 commitMutationEffectsOnFiber 中,处理了以下常见的 flags:
    • Placement: 表示需要将节点插入 DOM。
    • Update: 表示节点属性或样式更新。
    • Deletion: 表示需要从 DOM 中移除节点。
  • 特殊处理
    某些类型的节点(如 Class 组件和函数组件)需要处理额外的逻辑,例如:
    • 调用生命周期方法(如 componentWillUnmount)。
    • 清理资源(如 Effect 的销毁函数)。
  • 递归子节点
    在处理完当前节点的副作用后,继续递归处理其子节点,直到整个 Fiber 树被遍历完成。

注意事项

  • 不可中断性:与render阶段不同,commit阶段是同步且不可中断的。这意味着一旦开始执行commitMutationEffects,它将一直执行到完成,而不会被其他任务中断。
  • 性能优化:尽管commit阶段需要执行DOM操作,但React通过一些优化策略来减少不必要的DOM更新。例如,React使用虚拟DOM来比较新旧Fiber树之间的差异,并只更新那些实际发生变化的DOM节点
  • 副作用处理:除了DOM操作外,commitMutationEffects还可能处理其他类型的副作用,如类组件的生命周期方法调用(如componentDidUpdate)和函数组件的useEffect回调执行。然而,这些副作用通常会在commit阶段的不同子阶段中处理。

关键点说明

  1. 标记系统(Flags): React 使用 flags 属性来标记需要处理的副作用,比如
    Placement、Update、Deletion。

  2. 子树标记(SubtreeFlags): subtreeFlags 用于快速判断某个子树是否有副作用,可以跳过不需要处理的部分。

  3. 递归与遍历: nextEffect 的遍历逻辑是 React 树递归的重要模式,支持深度优先遍历整个 Fiber 树。

  4. 辅助函数: 像 commitPlacement、commitUpdate 和 commitDeletion
    是副作用执行的关键,它们最终会操作 DOM 或调用组件的生命

周期方法。

总结

commitMutationEffects是React Fiber架构中负责执行DOM更新的关键函数。它确保了React组件的状态变更能够正确地反映到真实的DOM结构上,并通过一些优化策略来提高性能。了解这个函数的工作原理有助于深入理解React的渲染流程和性能优化策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2276138.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32-学习笔记-6-】DMA

文章目录 DMAⅠ、DMA框图Ⅱ、DMA基本结构Ⅲ、不同外设的DMA请求Ⅳ、DMA函数Ⅴ、DMA_InitTypeDef结构体参数①、DMA_PeripheralBaseAddr②、DMA_PeripheralDataSize③、DMA_PeripheralInc④、DMA_MemoryBaseAddr⑤、DMA_MemoryDataSize⑥、DMA_MemoryInc⑦、DMA_DIR⑧、DMA_Buff…

IoT平台在设备远程运维中的应用

IoT平台是物联网技术的核心组成部分&#xff0c;实现了设备、数据、应用之间的无缝连接与交互。通过提供统一的设备管理、数据处理、安全监控等功能&#xff0c;IoT平台为企业构建了智能化、可扩展的物联网生态系统。在设备远程运维领域&#xff0c;IoT平台发挥着至关重要的作用…

浅谈云计算05 | 云存储等级及其接口工作原理

一、云存储设备 在当今数字化飞速发展的时代&#xff0c;数据已然成为个人、企业乃至整个社会的核心资产。从日常生活中的珍贵照片、视频&#xff0c;到企业运营里的关键业务文档、客户资料&#xff0c;数据量呈爆炸式增长。面对海量的数据&#xff0c;如何安全、高效且便捷地存…

网络传输层TCP协议

传输层TCP协议 1. TCP协议介绍 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一个要对数据的传输进行详细控制的传输层协议。 TCP 与 UDP 的不同&#xff0c;在于TCP是有连接、可靠、面向字节流的。具体来说&#xff0c;TCP设置了一大…

【Linux系列】`find / -name cacert.pem` 文件搜索

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【论文笔记】Sign Language Video Retrieval with Free-Form Textual Queries

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Sign Language Video Retr…

Observability:将 OpenTelemetry 添加到你的 Flask 应用程序

作者&#xff1a;来自 Elastic jessgarson 待办事项列表可以帮助管理与假期计划相关的所有购物和任务。使用 Flask&#xff0c;你可以轻松创建待办事项列表应用程序&#xff0c;并使用 Elastic 作为遥测后端&#xff0c;通过 OpenTelemetry 对其进行监控。 Flask 是一个轻量级…

网站目录权限加固

说明 在一个入侵链路中&#xff0c;往往是利用某个安全漏洞&#xff0c;向服务器写入或上传一个webshell&#xff08;后门&#xff09;&#xff0c;再通过webshell提权或进行后续渗透入侵行为。 这个过程中&#xff0c;获取webshell是最关键最重要的一个步骤&#xff0c;如能在…

qt QPainter setViewport setWindow viewport window

使用qt版本5.15.2 引入viewport和window目的是用于实现QPainter画出来的内容随着窗体伸缩与不伸缩两种情况&#xff0c;以及让QPainter在widget上指定的区域(viewport)进行绘制/渲染&#xff08;分别对应下方demo1&#xff0c;demo2&#xff0c;demo3&#xff09;。 setViewpo…

一些计算机零碎知识随写(25年1月)-1

我原以为世界上有技术的那批人不会那么闲&#xff0c;我错了&#xff0c;被脚本真实了。 今天正隔着画画呢&#xff0c;手机突然弹出几条安全告警通知。 急忙打开服务器&#xff0c;发现问题不简单&#xff0c;直接关服务器重装系统..... 首先&#xff0c;不要认为小网站&…

分布式锁Redisson详解,Redisson如何解决不可重入,不可重试,超时释放,主从一致问题的分析解决(包括源码简单分析)

目录 1. Redisson解决不可重入锁导致的死锁问题 2. 不可重试问题 Pub/Sub 的优势 锁释放的发布逻辑 3. 超时释放的问题 1. 锁的超时释放机制背景 2. 源码分析 2.1 锁的获取 2.2 看门狗机制 2.3 看门狗续期实现 2.4 手动设置锁的过期时间 总结 4. 主从一致性 问题…

【微服务】面试 4、限流

微服务限流技术总结 一、微服务业务面试题引入 在微服务业务面试中&#xff0c;限流是重要考点&#xff0c;常与分布式事务、分布式服务接口幂等解决方案、分布式任务调度等一同被考查。面试官一般会询问项目中是否实施限流及具体做法&#xff0c;回答需涵盖限流原因、采用的方…

爬虫基础之爬取歌曲宝歌曲批量下载

声明&#xff1a;本案列仅供学习交流使用 任何用于非法用途均与本作者无关 需求分析: 网站:邓紫棋-mp3在线免费下载-歌曲宝-找歌就用歌曲宝-MP3音乐高品质在线免费下载 (gequbao.com) 爬取 歌曲名 歌曲 实现歌手名称下载所有歌曲 本案列所使用的模块 requests (发送…

树莓派-5-GPIO的应用实验之GPIO的编码方式和SDK介绍

文章目录 1 GPIO编码方式1.1 管脚信息1.2 使用场合1.3 I2C总线1.4 SPI总线2 RPI.GPIO2.1 PWM脉冲宽度调制2.2 静态函数2.2.1 函数setmode()2.2.2 函数setup()2.2.3 函数output()2.2.4 函数input()2.2.5 捕捉引脚的电平改变2.2.5.1 函数wait_for_edge()2.2.5.2 函数event_detect…

Scala分布式语言二(基础功能搭建、面向对象基础、面向对象高级、异常、集合)

章节3基础功能搭建 46.函数作为值三 package cn . itbaizhan . chapter03 // 函数作为值&#xff0c;函数也是个对象 object FunctionToTypeValue { def main ( args : Array [ String ]): Unit { //Student stu new Student() /*val a ()>{"GTJin"…

CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞

漏洞描述 GiveWP 插件中发现了一个严重漏洞&#xff0c;该插件是 WordPress 最广泛使用的在线捐赠和筹款工具之一。该漏洞的编号为 CVE-2025-22777&#xff0c;CVSS 评分为 9.8&#xff0c;表明其严重性。 GiveWP 插件拥有超过 100,000 个活跃安装&#xff0c;为全球无数捐赠平…

支付宝租赁小程序提升租赁行业效率与用户体验

内容概要 在当今数字化的世界里&#xff0c;支付宝租赁小程序的出现构建了一种新的租赁模式&#xff0c;使得用户在使用过程中体验更加流畅。想象一下&#xff0c;你在寻找租赁服务时&#xff0c;不再需要繁琐的流程和冗长的等待&#xff0c;只需通过手机轻松点击几下&#xf…

关于使用FastGPT 摸索的QA

近期在通过fastGPT&#xff0c;创建一些基于特定业务场景的、相对复杂的Agent智能体应用。 工作流在AI模型的基础上&#xff0c;可以定义业务逻辑&#xff0c;满足输出对话之外的需求。 在最近3个月来的摸索和实践中&#xff0c;一些基于经验的小问题点&#xff08;自己也常常…

服务器/电脑与代码仓gitlab/github免密连接

git config --global user.name "xxxx" git config --global user.email "xxxxxx163.com" #使用注册GitHub的邮箱 生成对应邮箱的密码对 ssh-keygen -t rsa -b 4096 -C "xxxxxx163.com" 把公钥id_rsa.pub拷贝到github中 Setting----->…

【C语言系列】函数递归

函数递归 一、递归是什么&#xff1f;1.1尾递归 二、递归的限制条件三、递归举例3.1举例一&#xff1a;求n的阶乘3.2举例二&#xff1a;顺序打印一个整数的每一位 四、递归与迭代4.1举例三&#xff1a;求第n个斐波那契数 五、拓展学习青蛙跳台问题 一、递归是什么&#xff1f; …