react - 04.useLayoutEffect

49 阅读1分钟

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

4.useEffect和useLayoutEffect的工作原理

6644312185bd3f5eacb9afd0404ff68.png