useEffect 与 useLayoutEffect 有什么区别?
在React的源码中,useLayoutEffect
与useEffect
内部的实现其实是一样的,唯一不同的点在于useLayoutEffect
在执行的过程中是先调用React内部的mountLayoutEffect
,然后再调用mountEffectImp
l,而useEffect
执行的时候则是调用的mountEffect
,最后再调用的方法也跟useLayoutEffect
一样。那么mountLayoutEffect
与mountEffect
又有什么不同呢?唯一的不同点也只是触发的时机不同。
useEffect
是异步处理副作用,而useLayoutEffect
是同步处理副作用,
举例
举一个简单的例子,让我们需要修改页面中的DOM元素的颜色或者位置时,在useEffect
中修改DOM相关的属性会看到页面有明显的闪动,而在useLayoutEffect
中修改DOM相关的属性时,则不会发生闪动,这是为什么呢?其实这就是前面说的执行时机的不同。useEffect
能够适用于大部分场景,除了前面的例子中说的修改DOM元素的位置和颜色这样的场景不适用。而useLayoutEffect
因为是同步执行的,所以在DOM加载完成后再去进行操作就不会发生闪动,也因为useLayoutEffect
是同步执行的,所以我们也要避免在useLayoutEffect
执行需要大量计算的内容,如果需要大量计算,就会导致页面的卡顿,从而造成页面的阻塞
最后
useEffect与useLayoutEffect的函数签名是完全一致的,从代码角度来说,虽然它们是两个不同的函数,但是它们的使用方法是完全一致的,甚至一定程度上这两者是可以相互替换的,唯一的不同点是它们两的执行时机,并且官方给出的建议是在大部分场景下我们都可以使用useEffect来完成副作用的执行,只有当useEffect无法解决时再用useLayoutEffect进行处理,这样就不会产生相关的性能问题。