问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

React如何原生实现防抖?

发布网友 发布时间:2024-10-22 07:53

我来回答

1个回答

热心网友 时间:2024-10-22 18:17

大家好,我卡颂。

作为前端,想必你对防抖(debounce)、节流(throttle)这两个概念不陌生。

在React18中,基于新的并发特性,React原生实现了防抖的功能。

今天我们来聊聊这是如何实现的。

欢迎加入人类高质量前端框架研究群,带飞

useTransitionDemo

useTransition是一个新增的原生Hook,用于以较低优先级执行一些更新。

在我们的Demo中有ctn与num两个状态,其中ctn与输入框的内容受控。

当触发输入框onChange事件时,会同时触发ctn与num状态变化。其中触发num状态变化的方法(即updateNum)被包裹在startTransition中:

functionApp(){const[ctn,updateCtn]=useState('');const[num,updateNum]=useState(0);const[isPending,startTransition]=useTransition();return(<div><inputvalue={ctn}onChange={({target:{value}})=>{updateCtn(value);startTransition(()=>updateNum(num+1))}}/><BusyChildnum={num}/></div>);}

num会作为props传递给BusyChild组件。在BusyChild中通过while循环人为增加组件render所消耗的时间:

constBusyChild=React.memo(({num}:{num:number})=>{constcur=performance.now();//增加render的耗时while(performance.now()-cur<300){}return<div>{num}</div>;})

所以,在输入框输入内容时能明显感到卡顿。

在线示例地址

按理说,onChange中会同时触发ctn与num的状态变化,他们在视图中的显示应该是同步的。

然而实际上,输入框连续输入一段文字(即ctn的状态变化连续展示在视图中)后,num才会变化一次。

如下图,初始时输入框没有内容,num为0:

输入框输入很长一段文字后,num才变为1:

这种效果就像:被startTransition包裹的更新都有防抖的效果一样。

这是如何实现的呢?

什么是lane

在React18中有一套更新优先级机制,不同地方触发的更新拥有不同优先级。优先级的定义依据是符合用户感知的,比如:

用户不希望输入框输入文字会有卡顿,所以onChange事件中触发的更新是同步优先级(最高优)

用户可以接受请求发出到返回之间有等待时间,所以useEffect中触发的更新是默认优先级

那么优先级怎么表示呢?用一个31位的二进制,被称为lane。

比如同步优先级和默认优先级定义如下:

constSyncLane=0b0000000000000000000000000000001;constDefaultLane=0b0000000000000000000000000010000;

数值越小优先级越大,即SyncLane<DefaultLane。

那么React每次更新是不是选择一个优先级,然后执行所有组件中这个优先级对应的更新呢?

不是。如果每次更新只能选择一个优先级,那灵活性就太差了。

所以实际情况是:每次更新,React会选择一到多个lane组成一个批次,然后执行所有组件中包含在这个批次中的lane对应的更新

这种组成批次的lane被称为lanes。

比如,如下代码将SyncLane与DefaultLane合成lanes:

//用“按位或”操作合并laneconstlanes=SyncLane|DefaultLane;entangle机制

可以看到,lane机制本质上就是各种位运算,可以设计的很灵活。

在此基础上,有一套被称为entangle(纠缠)的机制。

entangle指一种lane之间的关系,如果laneA与laneB纠缠,那么某次更新React选择了laneA,则必须带上laneB。

也就是说laneA与laneB纠缠在一块,同生共死了。

除此之外,如果laneA与laneC纠缠,此时laneC与laneB纠缠,那么laneA也会与laneB纠缠。

那么entangle机制与useTransition有什么关系呢?

被startTransition包裹的回调中触发的更新,优先级为TransitionLanes中的一个。

TransitionLanes中包括16个lane,分别是TransitionLane1到TransitionLane16:

而transition相关lane会发生纠缠。

在我们的Demo中,每次onChange执行,都会创建两个更新:

onChange={({target:{value}})=>{updateCtn(value);startTransition(()=>updateNum(num+1))}

其中:

updateCtn(value)由于在onChange中触发,优先级为SyncLane

updateNum(num+1)由于在startTransition中触发,优先级为TransitionLanes中的某一个

当在输入框中反复输入文字时,以上过程会反复执行,区别是:

SyncLane由于是最高优先级,会被执行,所以我们会看到输入框中内容变化

TransitionLanes相关lane优先级比SyncLane低,暂时不会执行,同时他们会产生纠缠

为了防止某次更新由于优先级过低,一直无法执行,React有个过期机制:每个更新都有个过期时间,如果在过期时间内都没有执行,那么他就会过期。

过期后的更新会同步执行(也就是说他的优先级变得和SyncLane一样)

在我们的例子中,startTransition(()=>updateNum(num+1))会产生很多纠缠在一块的TransitionLanes相关lane。

过了一段时间,其中某个lane过期了,于是他优先级提高到和SyncLane一样,立刻执行。

又由于这个lane与其他TransitionLanes相关lane纠缠在一起,所以他们会被一起执行。

这就表现为:在输入框一直输入内容,但是num在视图中显示的数字过了会儿才变化。

总结

今天我们聊了useTransition内部的一些实现,涉及到:

lane模型

entangle机制

更新过期机制

最有意思的是,由于不同电脑性能不同,浏览器帧率会变动,所以在不同电脑中React会动态调节防抖的效果。

这就相当于不需要你手动设置debounce的时间参数,React会根据电脑性能动态调整。

原文:https://juejin.cn/post/7097406514360483877
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
石料加工服务可以全部交给第三人完成吗 山东沃尔德集团集团所辖公司介绍 齐鲁银行无忧贷和市民贷哪个好 什么叫补按揭 后按揭贷款什么意思 买房者续按揭有什么危害 加按揭是什么意思 八月中国最凉快的地方 八月份哪里最凉快,去哪旅游好?美丽的地方 乱字同韵字是什么意思 安徽省2011年高考文科467分,安徽省最好的大专是哪所,什么专业比较有前途... 2011年安徽省高考文科文综最高分是多少? ...碰到豪车维修需要50万 那么保险公司赔多少。我是不是还需 简要说说科技与创新之间的关系 发奖金算什么科目 奖金费计入什么科目 沉井概述 艾天竹艾天竹出现的背景 冶力关民俗文化 深圳天竹生态服饰有限公司产品介绍及特性 为什么我玩游戏时电脑提示我无法启动显卡驱动 冶力关位于哪里_甘肃冷门景点 冶力关风景区有着怎样绝美的景色? 稀盐酸浓度是多少 塑料杯底下7代表什么意思? 为什么一个男生会叫你哈儿,难道在他眼里,我真的很哈嘛 深圳老铁快推科技有限公司怎么样? 深圳自媒体平台是什么意思 湖南潇湘高考怎么看是否填报成功 想知道: 广州市 广州火车站坐地铁坐到白云区白云大道南怎么走 关于妹妹外貌的句子 贵阳格林豪泰酒店(喷水池店)交通位置 龙洞堡机场到市区 2500元预算i3独显lol剑灵主机配置,电源怎么选? 2500元i3独显Lol/剑灵游戏电脑配置,电源如何选择? 我电源本来是逾辉奇迹430的,烧掉了,现在要换个电源换什么?小白不太懂... 老挝金三角经济特区气候 哪位大虾知道仓木麻衣的Secret of my heart的罗马拼音 Tomorrow is the last Time罗马拼音 锦安面料的衣服第二年为什么会泛白第二年为什么会发白 武汉停车位多少钱一米 武汉野生动物王国的停车费现在是多少? 武汉野生动物王国停车方便吗 武汉野生动物王国停车场收费标准2024 我是学造价的,今年学校组织学生参加二级建造师考试,我们造价的靠这个证... QQ餐厅进不去,QQ牧场进不去.怎么办? 用招商银行信用卡在淘宝购物,后来退款了,退到了招商银行信用卡。这笔... 有没有关于促进日语学习的文章或者新闻的网站 附中文翻译的 ...学习日语》的文章,短点没有关系,内容通顺就可以了 中文版Flash动画制作经典实录228例图书目录 女生作图用笔记本 4000·5000左右的 最好漂亮点的 i5 大家帮忙推荐 谢谢...