react 【useEffect 和 useLayoutEffect 的区别】

前言

  useEffect和useLayout,都是react为函数组件提供的取代class组件周期,componentDidMount,componentDidUpdate的hook。它们的作用完全一致,只是调用的时机不同

调用时机

  useEffect:

    与componentDidMount、componentDidUpdate不同的是,在浏览器完成布局与绘制之后,传给useEffect的函数会延迟调用

  useLayoutEffect

    它相当于class组件的componentDidMountcomponentDid,它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新,

适用场景

  1.组件的入场动画

    (1)假定现在有一个弹框,假定需要在弹框出现的时候,加入一个缩放效果,那么使用useEffect和useLayoutEffect会有两种不同的结果

        useEffect:

          代码:

 const [ani, setAni] = useState(false); //是否展示弹框动画,默认为false

  useEffect(() => {
    setAni(true); //mount之后,显示动画
  }, []);

  return (
    <div className={s.msk}>
      <div className={s.wrap + ` ${ani ? s.animation : ""}`}>
        <span>弹框</span>
      </div>
    </div>

          样式:

.msk {
  ...//其他样式
  .wrap {
    transition: all 0.3s;
    transform: scale(0.7);
    .flex-center-w;
  }
  .animation {
    transform: scale(1);
  }
}

          效果: 可以看到弹框出现了由小变大动画

      现在将useEffect 改成useLayoutEffect可以看到,弹框一如既往,并没有出先由小变大的动画,为什么呢?

更新流程

    在使用useEffect时,浏览器第一次渲染时,并没有将.animation样式赋给弹框,而是在第二次渲染时赋予,弹框的样式发生了改变,所以会出现动画效果,而使用useLayoutEffect时,useLayouEffect内部的更新被同步更新至渲染输出上,在浏览器第一次渲染时.animation样式就已经赋给弹框,所以就不存在样式的改变,自然就没有动效

原文地址:https://www.cnblogs.com/wrhbk/p/15791860.html