useEffect与useLayoutEffect的区别演示

278 阅读1分钟

结论

useEffect : 在浏览器完成布局与绘制之后,传给 useEffect 的函数会延迟调用,也就是说如果在useEffect里有DOM相关操作,那么DOM变动后,会再次触发浏览器的绘制。

useLayoutEffect:它会在所有的 DOM变更之后同步调用 effect,也就是说useLayoutEffect 发生在DOM变更后,浏览器执行绘制之前。也就是说如果在useLayoutEffect里有DOM的相关操作,不会再次触发浏览器的绘制。

案例证明

  1. 相关代码

    const ref = useRef<HTMLDivElement>(null);
    ​
    useEffect(() => {
      // 刷新有过渡动画
      ref.current!.style.left = '600px';
    });
    useLayoutEffect(() => {
      // 刷新没有过渡动画
      // ref.current!.style.left = "600px";
    });
    console.time("a");
    console.timeEnd("a");
    ​
    return (
      <div className="compare-effect">
        <div className="container">
          <div className="box" ref={ref}></div>
        </div>
      </div>
    );
    
    .compare-effect {
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .container {
      height: 50px;
      width: 700px;
      background-color: aqua;
      position: relative;
    }
    .box {
      height: 50px;
      width: 50px;
      background-color: red;
      position: absolute;
      top: 0;
      left: 0;
      transition: left 3s;
    }
    
  2. 分析

    一段简单的过渡动画demo。初始位置在左侧0,目标位置在600。

    如果把box改变位置的代码放在useEffect里,浏览器会有一个初始位置的绘制以及改变后的绘制,所以会产生过渡动画。

useEffect

如果把box改变位置的代码放在useLayoutEffect里,此时浏览器只会绘制改变DOM之后的结果,所以不会产生过渡动画。

useLayoutEffect