useLayoutEffect Hook 概述
- 大部分情况下 useLayoutEffect 和 useEffect 没太大区别(用法格式都相同)
- 但是如果需要修改 DOM 的布局样式, 那么推荐使用
useLayoutEffect
为什么推荐在 useLayoutEffect 中修改 DOM 的布局样式?
- useEffect 函数会在组件渲染到屏幕之后才执行, 所以会可能会出现
闪屏
的情况 - useLayoutEffect 函数是在组件渲染到屏幕之前执行, 所以不会出现闪屏情况
首先来看 useEffect 会出现闪屏的情况代码如下:
App.js:
import React, {useRef, useState, useEffect} from 'react'; import './app.css' function Home() { const pRef = useRef(); useEffect(() => { console.log('组件被挂载或更新完成 - useEffect'); pRef.current.style.left = '0px'; pRef.current.style.left = '500px'; return () => { console.log('组件即将被卸载 - useEffect'); } }); return ( <div> <p ref={pRef}></p> </div> ) } export default function App() { const [show, setShow] = useState(true); return ( <div> {show && <Home/>} <button onClick={() => { setShow(!show) }}>切换 </button> </div> ) }
如上代码大致意思就是通过一个按钮来控制 Hmoe 组件的显示与隐藏。
app.css:
p { width: 100px; height: 100px; position: relative; left: 0; top: 0; background: red; }
运行项目然后点击切换按钮,你会发现在切换的过程当中会有一闪而过的效果这就是所谓的闪屏。
在来看 useLayoutEffect 的效果代码如下:
import React, {useRef, useState, useLayoutEffect} from 'react'; import './app.css' function Home() { const pRef = useRef(); useLayoutEffect(() => { console.log('组件被挂载或更新完成 - useLayoutEffect'); pRef.current.style.left = '0px'; pRef.current.style.left = '500px'; return () => { console.log('组件即将被卸载 - useLayoutEffect'); } }); return ( <div> <p ref={pRef}></p> </div> ) } export default function App() { const [show, setShow] = useState(true); return ( <div> {show && <Home/>} <button onClick={() => { setShow(!show) }}>切换 </button> </div> ) }
可以很清晰的发现,两者的效果是完全不同的。
useEffect 和 useLayoutEffect 的区别
执行时机不同:
- 如果是挂载或者更新组件, 那么 useLayoutEffect 会比 useEffect 先执行
import React, {useRef, useState, useEffect, useLayoutEffect} from 'react'; import './app.css' function Home() { const pRef = useRef(); useEffect(() => { console.log('组件被挂载或更新完成 - useEffect'); return () => { console.log('组件即将被卸载 - useEffect'); } }); useLayoutEffect(() => { console.log('组件被挂载或更新完成 - useLayoutEffect'); return () => { console.log('组件即将被卸载 - useLayoutEffect'); } }); return ( <div> <p ref={pRef}></p> </div> ) } export default function App() { const [show, setShow] = useState(true); return ( <div> {show && <Home/>} <button onClick={() => { setShow(!show) }}>切换 </button> </div> ) }
- 如果是卸载组件, 那么 useEffect 会比 useLayoutEffect 先执行
- useEffect: 同步
- useLayoutEffect: 异步
什么时候使用 useEffect
- 在绝大多数的情况下能用 useEffect, 就用 useEffect
什么时候用 useLayoutEffect
- 只有在需要组件挂载之后更新 DOM 的布局和样式的时候才使用 useLayoutEffect
为什么要使用 useLayoutEffect 来更新 DOM 布局和样式
useEffect 是组件已经渲染到屏幕上了才执行,useLayoutEffect 是组件还没有渲染到屏幕上就会执行,所以如果在组件已经渲染到屏幕上了, 才去更新 DOM 的布局和样式, 那么用户体验不好, 会看到闪屏的情况,而如果是在组件还没有渲染到屏幕上, 就去更新 DOM 的布局和样式, 那么用户体验更好, 看不到闪屏情况。
最后
本期结束咱们下次再见👋~
🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗