当前位置:首页 > 科技  > 软件

精准解析 useLayoutEffect 与 useEffect 的执行时机

来源: 责编: 时间:2024-01-17 10:13:53 149观看
导读我们前面花了大量篇幅,从基础、理论、实践、总结几个方面,全方位的为大家分析了 useEffect。除此之外,React 还提供了一个与 useEffect 几乎一样的 hook,它就是useLayoutEffect。我们约定,useEffect 传入的第一个参数为 ef

fQp28资讯网——每日最新资讯28at.com

我们前面花了大量篇幅,从基础、理论、实践、总结几个方面,全方位的为大家分析了 useEffect。除此之外,React 还提供了一个与 useEffect 几乎一样的 hook,它就是useLayoutEffect。fQp28资讯网——每日最新资讯28at.com

我们约定,useEffect 传入的第一个参数为 effect,useLayoutEffect 传入的第一个参数为 layoutEffect。fQp28资讯网——每日最新资讯28at.com

他们的语法为:fQp28资讯网——每日最新资讯28at.com

// 中括号表示参数可选useEffect(effect[, deps])
useLayoutEffect(layoutEffect[, deps])

两个 hook 有高度相似的语义。fQp28资讯网——每日最新资讯28at.com

第一个参数 layoutEffect 为一个函数,定义为副作用执行逻辑,我们也可以在 layoutEffect 中定义返回函数。当依赖项发生了变化时,返回函数会使用依赖项旧值首先执行,然后再执行 layoutEffect。fQp28资讯网——每日最新资讯28at.com

useLayoutEffect(() => {  // ...    return () => {}}, [state])

第二个参数为依赖项数组。React 内部会使用 Object.is 去比较依赖项是否发生了变化,我们通常会选择使用 state 或者 props 等响应性数据作为依赖项。依赖项也可以不传,此时 layoutEffect 在每次状态发生变化时都会执行。fQp28资讯网——每日最新资讯28at.com

useLayoutEffect 与 useEffect 唯一的区别在于 effect 与 layoutEffect 执行时机的不同。fQp28资讯网——每日最新资讯28at.com

我们借助一个例子来仔细分析他们的准确执行时机。fQp28资讯网——每日最新资讯28at.com

首先是 useEffect。fQp28资讯网——每日最新资讯28at.com

const [count, setCount] = useState(0)useEffect(() => {  document.title = `React ${count}`})

effect 会在组件渲染完成之后执行。这里组件渲染完成的意思是当组件内容已经呈现在页面上之后,effect 再执行,具体的步骤如下图所示:fQp28资讯网——每日最新资讯28at.com

fQp28资讯网——每日最新资讯28at.com

在事件循环中, effect 是被定义为宏任务,在下一轮循环执行。fQp28资讯网——每日最新资讯28at.com

然后是 useLayoutEffect。fQp28资讯网——每日最新资讯28at.com

const [count, setCount] = useState(0)useLayoutEffect(() => {  document.title = `React ${count}`})

layoutEffect 会在组件渲染之前执行。具体的步骤如下图。fQp28资讯网——每日最新资讯28at.com

fQp28资讯网——每日最新资讯28at.com

但是这里如果只是这样理解的话,估计很多人并不太清晰具体是怎么回事。因为这样的表达并没有说清楚具体的执行时刻。更准确的说法是在 commit 之后,组件内容绘制呈现到屏幕之前。fQp28资讯网——每日最新资讯28at.com

例如我们有这样一段代码。fQp28资讯网——每日最新资讯28at.com

// 此时已经对DOM发送改变的指令div.style.color = 'red'layoutEffect()

layoutEffect 紧随 DOM 修改指令发出之后执行,此时虽然 DOM 指令已经发出,但是在浏览器的机制中,内容绘制是一个异步的过程,这会儿绘制并没有执行。fQp28资讯网——每日最新资讯28at.com

因此在事件循环中,layoutEfect 被定义为类似于 Promise 的微任务,在 DOM 指令修改之后,内容绘制之前执行。fQp28资讯网——每日最新资讯28at.com

后续影响

大家可以猜想一下,如果我们在 layoutEffect 中直接去修改 state,会发生什么事情。fQp28资讯网——每日最新资讯28at.com

看看下面这个例子:fQp28资讯网——每日最新资讯28at.com

function Demo() {  const [count, setCount] = useState(0)    useLayoutEffect(() => {    if (count == 0) {      setCount(1)    }  }, [count])      return (    <div>      <div>{count}</div>      <button         onClick={() => setCount(0)}      >        reset 0      </button>    </div>  )}

我们在 state 中声明一个变量 count,初始值设置为 0,并定义 layoutEffect,其中的逻辑就是当 count == 0 时,将 count 设置为 1。fQp28资讯网——每日最新资讯28at.com

添加一个按钮,当按钮点击时,把 count 重新设置为 0。fQp28资讯网——每日最新资讯28at.com

大家思考一下,此时,页面上的显示结果,会在 0 和 1 之间来回切换吗?fQp28资讯网——每日最新资讯28at.com

答案是不会。fQp28资讯网——每日最新资讯28at.com

因为当我们执行 layoutEffect 时,UI 并没有进入事件循环的绘制流程,此时还处于 JS 逻辑的执行过程中,那么这个时候执行 setCount,整个逻辑会重新执行,对于浏览器而言,JS 针对同一个 UI 发出了两条不同的指令,在浏览器的渲染机制中,也会发生收集行为,将这两条指令进行合并,最后只执行一条。fQp28资讯网——每日最新资讯28at.com

// setCount(0)div.innerHTML = 0// setCount(1)div.innerHTML = 1

如上例,当 setCount(0) 与 setCount(1)  执行完之后,实际上是发出了两条修改元素内容的指令给到浏览器。fQp28资讯网——每日最新资讯28at.com

当我们使用 useLayoutEffect 时他可能会覆盖你想要执行的渲染内容,也有可能会阻塞你的正常渲染过程,因此我们在使用它时,需要精确把控他的执行时机,防止出现你不想看到的结果。fQp28资讯网——每日最新资讯28at.com

但是很明显我们可以看到 layoutEffect 的执行时机比 effect 更早。因此我们也可以在 layoutEffect 中,执行一些轻量的,不直接影响 state 的逻辑。fQp28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-63227-0.html精准解析 useLayoutEffect 与 useEffect 的执行时机

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Java高频面试题:过滤器和拦截器两位难兄难弟区别

下一篇: 这篇文章彻底让你了解Java与RPA

标签:
  • 热门焦点
  • K60 Pro官方停产 第三方瞬间涨价

    K60 Pro官方停产 第三方瞬间涨价

    虽然没有官方宣布,但Redmi的一些高管也已经透露了,Redmi K60 Pro已经停产且不会补货,这一切都是为了即将到来的K60 Ultra铺路,属于厂家的正常操作。但有意思的是该机在停产之后
  • Flowable工作流引擎的科普与实践

    Flowable工作流引擎的科普与实践

    一.引言当我们在日常工作和业务中需要进行各种审批流程时,可能会面临一系列技术和业务上的挑战。手动处理这些审批流程可能会导致开发成本的增加以及业务复杂度的上升。在这
  • 微信语音大揭秘:为什么禁止转发?

    微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 从零到英雄:高并发与性能优化的神奇之旅

    从零到英雄:高并发与性能优化的神奇之旅

    作者 | 波哥审校 | 重楼作为公司的架构师或者程序员,你是否曾经为公司的系统在面对高并发和性能瓶颈时感到手足无措或者焦头烂额呢?笔者在出道那会为此是吃尽了苦头的,不过也得
  • “又被陈思诚骗了”

    “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 大厂卷向扁平化

    大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 三星电子Q2营收60万亿韩元 存储业务营收同比仍下滑超过50%

    三星电子Q2营收60万亿韩元 存储业务营收同比仍下滑超过50%

    7月27日消息,据外媒报道,从三星电子所发布的财报来看,他们主要利润来源的存储芯片业务在今年二季度仍不乐观,营收同比仍在大幅下滑,所在的设备解决方案
  • 3699元!iQOO Neo8 Pro顶配版今日首销:1TB UFS 4.0同价位唯一

    3699元!iQOO Neo8 Pro顶配版今日首销:1TB UFS 4.0同价位唯一

    5月23日,iQOO推出了全新的iQOO Neo8系列,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更是首发搭载了联发科天玑9200+旗舰
  • 电博会与软博会实现

    电博会与软博会实现"线下+云端"的双线融合

    在本次“电博会”与“软博会”双展会利好条件的加持下,既可以发挥展会拉动人流、信息流、资金流实现快速交互流动的作用,继而推动区域经济良性发展;又可以聚
Top