我相信,大部分的同学在日常编码中,都是使用useEffect(包括我自己),所以我对useLayoutEffect的认知其实一直很少,一直处于只是知道有这个hook的水平
最近在梳理react知识体系时,又发现了这个我一直似懂非懂的hook,这次我就专门好好研究了它,本篇文章就准备好好聊聊关于它和useEffect的东西,废话不多说,开搞!
什么是useEffect和useLayoutEffect
在讲它俩的区别之前,我们首先简单看下关于它们各自的定义与用法
- useEffect:使用
useEffect
完成副作用操作,你可以把 effect 看作从 React 的纯函数式世界通往命令式世界的逃生通道。默认情况下,effect 将在每轮渲染结束后执行,也可以给它传递依赖数组,从而只在对应依赖项发生变化时才执行回调函数。可以在回调函数里返回一个函数,该函数用于清除上一轮的副作用 - useLayoutEffect:其函数签名与
useEffect
相同,也就说它与useEffect的用法完全一致
useEffect和useLayoutEffect的区别
它俩的区别其实在我看来非常细微,但是实际效果却大不相同,如果不了解的情况下,错误使用它俩,很大概率会影响应用的性能与流畅度,下面就来说说它俩的区别
它俩其实也就存在一个区别:调用时机不一样
- useEffect:是在浏览器进行绘制 完成后 执行的回调,也就是说回调函数的执行,不会阻塞页面的绘制
- useLayoutEffect:是在dom更新完成之后,浏览器进行绘制之前调用的回调,浏览器的绘制会等待其回调函数的执行完成后才开始
由于它俩的执行时机不同,因此会造成不同的负面影响
- useEffect:由于其执行时机在页面绘制之后,因此如果在回调里有操作可见的dom,比如进行移动,那么会造成元素的闪烁
- useLayoutEffect:由于页面的绘制需要等待其回调执行完成,如果在回调里存在耗时的任务,那么就会影响浏览器的绘制,造成页面更新的不流畅,因此需要避免执行耗时任务
下面给出两个动图,直观感受下两个hook的效果区别
useEffect:
useLayoutEffect: