react原理-transition概念

news2024/12/22 18:48:46

在react18之中,引入了transition的概念。而且有一个新的api和两个新的hooks

  • startTransition
  • useTransition
  • useDeferredValue

场景应用:
比如通过输入框输入内容更新列表内容,对于用户来说,输入框输入之后立马反馈的优先级是高过于列表更新的优先级的。但是对于18之前的版本来说,更新没有分优先级,导致如果数据量大,列表更新慢,用户输入在输入框输入内容后很慢才能得到反馈,用户体验差。

而transition可以让列表更新的优先级降低,让用户输入的先处理,然后再处理列表更新。18之后开启了concurrent mode模式,更新也分了优先级的概念。

用法:

setData1(e)
startTransition(()=>{ 
	setData2(e)
})

将需要延迟更新的任务放到startTransition去执行,这样里面的更新任务就会被赋予transition的优先级。

setTimeout

setTimeout也有类似于延迟更新的效果,比如

setData1(e)
setTimeout(()=>{ 
	setData2(e)
}, 200)
  • 跟startTransition相比,startTransition的本质是,将任务的优先级降低,所以当用户一致输入的时候,优先级较低的任务,不会阻碍输入框的回显。并且transition的时机,是比setTImeout更加合适的,他会在没有搞优先级任务的情况下,第一时间处理。而setTimeout的时间是人为控制的,不够准确。
  • 第二则是,当渲染任务多的时候,setTImeout仍会阻碍搞优先级的任务,因为等延时时间一到,setTImeout里面的任务就会被执行,此时仍会阻止页面的交互。但是transition就不同了,在conCurrent mode下,react将该任务的优先级降低,等到浏览器空闲的时候才会执行。
  • 但也不是说startTransition的任务永远不会影响主流程,因为在react中,每个任务都有过期时间,而过渡任务的过期时间比紧急任务长了很多而已,但是当该过渡任务迟迟得不到处理,并且已经过期的时候,react就会先处理这个过期的过渡任务,然后再继续调度。具体可以了解react的schedlue模块。
防抖
  • 输入框的内容经常跟防抖节流打交道,但是其本质也是通过setTimeout,只不过控制了render的次数,而且防抖节流也需要人为的控制时间,而使用startTransition就不需要考虑这么多。

transition功能特性

transition顾名思义过度,状态更新的任务一般有两种,一种是紧急更新任务,比如用户交互行为,点击,输入等等。
而另一种则是过渡更新任务,比如上面列表的更新,这种任务的优先级低于紧急更新任务。

startTransition

startTransition(fn)

同步执行,但是fn里面的更新会被标记transition的优先级。也就是优先级更低了。

useTransition

startTransition只是用来降低优先级的,也就是过渡,但是过渡了多久我们需要一个状态来知道。useTransition就是用来做这个事情的。

const [isPending, startTransition] = useTransition()

startTransition(fn)

useTransition返回两个值,第一个就是是否正在过渡到控制变量,第二个就是跟startTransition用法一样的,用来降低任务优先级的函数。但任务处于过渡阶段的时候,isPending为true,告诉开发者,目前该任务正在过渡。

useDeferredValue

上述的startTransition和useTransition本质都是将一些任务的优先级降低。
而useDeferredValue可以让状态滞后更新。实现效果类似于transiton,当紧急的任务执行之后,再得到新的状态,而这个新的状态就是deferredValue。

跟useTransition的区别

同:内部实现一样,都是将任务标记为过渡更新任务。
别:

  • useTransition是将处理一段逻辑,将任务变为过渡任务,useDeferredValue是将原值通过过渡任务后得到新的值,他是产生一个新的状态。
  • 其次就是useDeferredValue的更新会更滞后于useTransition,因为内部是使用useEffect来调用startTranstion的。下面原理环节会讲到。

原理

startTransition

startTransition的源码实现

在这里插入图片描述
他的本质有点类似于17之前的事件更新,通过开关ReactCurrentBAtchConfig.transition
ReactCurrentBAtchConfig.transition默认值是null,再需要更新过渡任务的时候,将其置为{},这样startTransition里面的函数执行的时候,就会判断ReactCurrentBAtchConfig.transition以此来将其优先级降低。
在这里插入图片描述

useTransition

在这里插入图片描述
mount更新阶段,执行的函数是mountTransition,update阶段执行的函数是updateTransition
在这里插入图片描述
如图是mountTransition,本质很简单,就是通过调用mountState产生一个状态,然后通过startTransition绑定默认参数,调用moutnWorkInProgressHook创建hooks对象,跟其他hook链接,最后这个hooks.memoizedState保存的就是startTransition这个函数。

注意这里的startTransition跟上面的startTransition不一样,

在这里插入图片描述
如上,则是useTransition返回的第二个参数,本质就是先调用setPending(ture),然后切换transitiion上下文,让setPending(false)的更新也变成了过渡任务,这样setPending(false)和callback的任务优先级相同,他们会同时处理。

所以useTransition可以看成useState+startTransition
在这里插入图片描述

useDeferredValue

在这里插入图片描述
在这里插入图片描述
useDeferredValue本质也是调用了useState+useEffect,通过监听value值的改变,触发useEffect回调函数的更新,再去切换tranition上下文,更新setValue(value)
所以useDeferredValue可以看成:useState+useEffect+startTransition。
在这里插入图片描述

看看react如何通过判断transition上下文。

const [data, setData] = useState({})
startTransition(()=>setData({}))

一般startTransition里面函数,存在着触发更新的动作,比如useState的第二个参数setState,他们会创建update,更新优先级,开始调度。具体可以看hooks实现逻辑
所以重点看看产生update时候的优先级的处理,以setState为例子
useState的第二个参数,实际上是调用dispatchSetState函数
在这里插入图片描述
在这里插入图片描述
requestUpdateLane就是用来获取当前update的优先级的。来看具体实现
在这里插入图片描述
第一个判断就是判断是否是同步模式下,也就是18之前的模式,他不支持优先级的概念。

在这里插入图片描述

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

其次就是判断是否是transition的上下文,判断方式也很简单粗暴,直接判断ReactCurrentBatchConfig.transition是否不等于null,是的话就表示处于transition的更新。
然后返回currentEventTransitionLane,也就是transition的优先级
在这里插入图片描述

在这里插入图片描述

这也就解释了通过切换transition上下文,产生的update的优先级并不一样。
然后处理这个update的时候
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,setSe 产生的update的确走了这个逻辑,最后返回的优先级就是64。
然后将update插入hooks的update连表上,更新调用scheduleUpdateOnFiber开始新的一轮调度。
然后最后会执行ensureRootIsScheduled函数,该函数根据当前的优先级,调用schedule模块提供的schedule_callback函数调度任务。如下:
在这里插入图片描述

对于64的优先级,被分配到了normalPriority的优先级,
在这里插入图片描述
然后通过注册任务,开启调度。

自此,整个transition的流程就已经走通了。

总结:

  • transition过渡,就是将一些不紧要的任务降低其优先级,使其不阻塞高优先级的任务。

  • 具体实现就是通过切换transition上下文,使产生的udpate获取更低的优先级,这样调度的时候过期时间就会更长,从而不会阻塞高优先级的任务。

  • 文章通过学习掘金的《react进阶实践指南》作为笔记产出,文中图片部分来自《react进阶实践指南》

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

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

相关文章

VS ChatGPT 中文版插件安装

1.打开Visual Studio Code 2.搜索chatGpt中文版 3.安装完后,重启一下软件 有国模式和国外模式,更多的教程请看插件作者的视频教程

分布式事物

Seata实践 XA模式 AT模式 TCC模式 性能 Saga模式 高可用------集群的形式 Seata实践解决方案 解决方式 Seata 引入服务协调者模式 实践步骤: 分布式事物的入口方法,会调用其他的微服务,每次调用的服务都是一个分支事物调用了多少个分支事…

SpringSecurity 认证实现

在之前一篇 博客 已经说明了 SpringSecurity 认证与授权的原理。这篇用来具体实现一下。 1、新建SecurityConfig 并创建认证管理器 Bean public AuthenticationManager authenticationManager() {... }2、新建认证提供者 Configuration public class SystemUserPasswordAuth…

Oracle项目管理之PrimaveraUnifier组织-业主/合作伙伴公司

目录 一、业主公司 二、合作伙伴公司 三、成员公司 Oracle Primavera Unifier 是企业项目协同管理系统,在国际化项目管理中,在进行常规的业务管理之外,对合同公司/EPC或分包供应商也有一定的管理要求,在Unifier中为了更好的实现…

sja1000 CAN驱动学习、调试记录(基于PeliCan Mode)

一、基础知识 网上讲sja1000 CAN总线控制器的资料很多,这里放一个引路贴:(151条消息) CAN总线控制器SJA1000_FATE的博客-CSDN博客_sja1000 BasicCAN Mode:仅支持11位的ID。 PeliCan Mode:在扩展模式下,允许使用 11 位 …

找出DataFrame中指定数据类型的列:select_dtypes()函数

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 找出DataFrame中指定数据类型的列 select_dtypes()函数 选择题 下列说法错误的是? import pandas as pd myDF pd.DataFrame({A:[1,2],B:[1.0,2.0],C:[a,b]}) print("【显示】myDF&qu…

leecode#同构字符串#反转链表

题目描述: 给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一…

ReentrantLock详解

JUC中的锁API 在juc中有一个Lock接口他的作用和synchronized相似都是为了保证线程安全性提供的解决方案 Lock中定义了一系列释放锁和抢占锁相关的API lock() 抢占锁资源 如果当前线程没有抢占到锁 则阻塞 tryLock() 尝试抢占锁资源 如果抢占成功则返回true 否则返回false unlo…

简单的深度活体智能记忆模型

🍿*★,*:.☆欢迎您/$:*.★* 🍿 正文

基于Antd Input组件自定义Input的成功状态

前言 Ant Design的Input组件的有一个状态的Api 需求 公司自研UI组件,在Antd的基础上进行开发。其中Input组件除了警告与错误状态外,还增加了成功的状态。如下图⬇️ 开发实现 方案一:覆盖CSS样式 一开始准备通过判断状态来增加类名&am…

软件工程习题

软件工程第一章 软件与软件工程作业第二章 可行性研究作业第三章 需求分析作业第四章 总体设计作业第五章 详细设计作业第六章 软件编码测验第七章 软件测试作业选择判断简答题第一章 软件与软件工程作业 一、单选题(共7题,58.1分) 1、软件是…

刷题13-左右两边子数组的和相等

题目012-左右两边子数组的和相等 思路:用到了三个循环,从头到尾遍历数组,比较左右两边数组的和是否相等,当然这种思路时间复杂度也比较高 核心代码: class Solution {public int pivotIndex(int[] nums) {int sum1,…

6.2 、MyBatis 高级映射(resultMap 标签多表联查 , 一对多,多对一关系)

文章目录一、实现多表联查(association 标签)1、实现多对一关系结果集映射二、实现多表联查(collection 标签)一、实现多表联查(association 标签) association 标签: 实现一对一,多…

因果推断1--基本方法介绍(个人笔记)

目录 一、因果推断介绍 1.1 什么是因果推断 1.2为什么研究因果推断 1.3因果推断阶梯 1.4因果推断问题分类 二、因果推断理论框架 2.1 定义(这些定义后面会经常用到) 2.2 Assumptions(三大基本假设) 三、因果效应估计 3.1 因果效应…

JavaEE【Spring】:SpringBoot 配置文件

文章目录一、配置文件的作用二、配置文件的格式1、注意2、说明三、properties 配置文件说明1、基本语法2、读取配置文件① 注意3、优缺点四、yml 配置文件说明1、基本语法2、yml 使用进阶① yml 配置不同数据类型及 nullⅠ. yml 配置读取Ⅱ. 练习a. 值为 null 的配置b. 根本不存…

利用云服务器发布项目

前言 平时开发我会写一些小demo,我自己觉得有用的会集中起来形成一个项目,本来想利用gitee的gitee page直接部署出来,但后面了解了下,它只支持官网之类的静态页面,无法与后台数据交互,想要完整的服务还是得…

数据分析业务场景 | 用户画像

一.概况 定义 是根据用户的一系列行为和意识过程建立起来的多维度标签;是根据用户人口学特征,网络浏览内容,网络社交活动和消费行为等信息而抽象出的一个标签化的用户模型;首要任务:根据业务需求整理和数据情况分析建…

Springboot redirect重定向使用RedirecAtrributes传递数据

参考资料 【转载】关于重定向RedirectAttributes的用法RedirectAttributes 的使用 目录前期准备一. RedirecAtrributes重定向传参三. 重定向目标页面接收参数前期准备 ⏹配置文件 server:servlet:context-path: /jmw⏹访问url http://localhost:8080/jmw/test16/init?name…

NX二次开发(C#)-UI Styler-选择对象TaggedObject转换为Body、Face等对象

文章目录 1、前言2、选择对象的过滤器2、选择对象类型为TaggedObject3、TaggedObject转换为Face类型1、前言 前面的博客中已经写过了UI Styler中选择对象(selection)的一些内容,但是依然有读者不知道运用,本文将在前文的基础上更加深入的介绍选择对象的应用(建议与https:/…

DevExpress Universal添加对.NET 7的支持

DevExpress Universal添加对.NET 7的支持 DevExpress已经发布了整个产品系列的主要更新。 CodeRush Ultimate 22.2-为许多重构添加了核心性能优化和增强。 DevExpress.NET MAUI 22.2-添加了对Material Design 3指南的支持,以及对数据网格的自定义过滤、排序和分组。…