react uselayouteffect和useeffect区别

393 阅读1分钟

``

区别:

执行时机不同:

useLayoutEffect:DOM 发生了改变之后,浏览器绘制之前执行的

   useEffect: 浏览器完成渲染之后

执行过程不同:

  useLayoutEffect 同步执行,阻塞浏览器重新绘制 ,可能会导致页面渲染的卡顿

  useEffect 异步执行,二次渲染问题,不阻塞浏览器绘制

执行顺序:

useLayoutEffect【微任务】  在 useEffect【宏任务】 之前执行

为什么会二次渲染:

产生二次渲染问题,第一次渲染的是旧的状态,接着下一个事件循环中,执行改变状态的函数,组件又携带新的状态渲染,在视觉上,就是二次渲染。

useEffect 的回调函数是【异步宏任务】,在下一轮事件循环才会执行。根据 JS 线程与 GUI 渲染线程互斥原则,在 JS 中页面的渲染线程需要当前事件循环的宏任务与微任务都执行完,才会执行渲染线程,渲染页面后,退出渲染线程,控制权交给 JS 线程,再执行下一轮事件循环。

如下图:拿这个代码跑一遍就可以复现二次渲染了

import {  useCallback, useEffect,useLayoutEffect, useState } from 'react';
export default () => {
    const [num, setNum] = useState(Math.random())

    useEffect(() => {
        console.log(num,'11')
      if (num === 0) {
        setNum(Math.random())
      }
    }, [num])
  
    return (
      <>
        <h1>num 的值是:{num}</h1>
        <button onClick={() => setNum(0)}>重置 num</button>
      </>
    )
  } 

由下图中可以看到使用useEffect,num先是变为了0,在变成的随机数,二次渲染。 而useLayoutEffect,直接变成随机数,没有二次渲染问题。

image.png