useLayoutEffect和useEffect很相似,也接收一个函数和一个数组,但是只有在数组里面的值改变的情况下,才会再次执行副作用,并且也可以返回一个函数
1.useEffect和useLayoutEffect的区别:
useEffect是异步执行的,useLayoutEffect是同步执行的
useEffect的执行时机是浏览器完成渲染之后,useLayoutEffect的执行时机是浏览器将内容渲染到界面之前
2.useLayoutEffect作用:
当useEffect的操作需要处理DOM,并且处理DOM的过程中会改变页面的样式时,就会用到useLayoutEffect,否则可能会出现闪屏问题,useLayoutEffect里的callback函数会在DOM更新完成后立即执行,并且会在浏览器进行任何绘制之前运行完成,否则会阻塞浏览器的绘制
3.举个例子:
import { useEffect, useState } from 'react'
const App = () => {
const [num, setNum] = useState(0)
useEffect(() => {
if (num === 0) {
const randomNum = 10 + Math.random() * 200
setNum(randomNum)
}
}, [num])
const handleClick = () => {
setNum(0)
}
return (
<>
<div>{num}</div>
<button onClick={handleClick}>Click</button>
</>
)
}
export default App
我们写一个生成随机数的例子,当点击按钮的时候,会发现随机出来的数字闪烁,这是因为每次点击按钮的时候,num都会更新为0,之后useEffect又把num改为一串随机数,所以会出现闪烁
但是将useEffect改成useLayoutEffect,就不会闪烁,这是因为,当num更新为0的时候,页面并不会被渲染,而是等待useLayoutEffect内部状态修改后才会更新页面
import { useLayoutEffect, useState } from 'react'
const App = () => {
const [num, setNum] = useState(0)
useLayoutEffect(() => {
if (num === 0) {
const randomNum = 10 + Math.random() * 200
setNum(randomNum)
}
}, [num])
const handleClick = () => {
setNum(0)
}
return (
<>
<div>{num}</div>
<button onClick={handleClick}>Click</button>
</>
)
}
export default App