测试用例
首先 贴上一个我觉得效果最直观的一个🌰!
import React, { useEffect, useLayoutEffect, useState, useRef } from "react"
function App() {
const [data, setData] = useState(1)
const currentDate = new Date().getTime()
// 手动延迟3s
while (currentDate + 3000 > new Date().getTime()) {}
// useEffect(() => {
// if (data === 0) {
// setData(String(Math.random()))
// }
// }, [data])
useLayoutEffect(() => {
if (data === 0) {
setData(String(Math.random()))
}
}, [data])
return (
<>
<div>
<button onClick={() => setData(0)}>CHANGE</button>
</div>
<div style={{ width: "fit-content", display: "flex", background: "pink" }}>{data}</div>
</>
)
}
export default App
如果但以此🌰来看的话,
1、如果我们放开的是useEffect的代码注释,页面表现会3S后变成0,然后再3S后变成一个随机数。
2、如果我们放开的是useLayoutEffect的代码注释,页面的表现则会是6S后直接变成一个随机数。
结合这个🌰我们再来理解useEffect和useLayoutEffect的定义差别
1、useEffect是异步的,不会阻塞页面渲染,在dom挂载到页面之后执行。
2、useLayoutEffect是同步的,在dom更新之后挂载到页面之前执行,会阻塞页面渲染。
流程分析
所以,在useEffect例中,通过将data变成0,函数重新执行,延迟3S后更新dom之后渲染。页面变化为0,然后执行useEffect里面的函数,data变为随机数,再次延迟3S,更新dom,xuanran,页面变化为随机数
在useLayoutEffect中,将data变成0,函数重新执行,延迟3S后更新 更新dom并且在页面挂载之前执行了useLayoutEffect,所以函数再次执行,又延迟了3S,完成挂载,挂载用时6S