自学内容网 自学内容网

【useLayoutEffect Hook】在浏览器完成布局和绘制之前执行副作用

前言

useLayoutEffect 是 React 中的一个 Hook, 类似于 useEffect,但有一个关键的区别:它会在所有的 DOM 变更之后同步调用 effect。这意味着它可以读取 DOM 布局并同步重新渲染。如果你需要执行副作用并且这些副作用依赖于 DOM 布局(例如,获取元素的尺寸或位置),你应该使用 useLayoutEffect

语法

useLayoutEffect(setup, dependencies?)

useLayoutEffect的语法和useEffect一样。

  • setup: 处理副作用的函数。
  • dependencies: 依赖项。

useLayoutEffect 对比 useEffect

  • 执行时机: useLayoutEffect 在浏览器绘制之前同步执行,useEffect则是在布局会绘制之后执行。
  • 执行方式: useLayoutEffect同步执行useEffect 异步执行
  • 堵塞浏览器渲染: useLayoutEffect会堵塞useEffect不会堵塞

结论:
若是需要同步读取或更改DOM,或者需要解决页面的闪烁问题,则需要使用useLayoutEffect
否则,应该优先考虑使用useEffect

下面测试响应的特性:

示例

import { useEffect, useLayoutEffect, useRef } from 'react';

export default function App() {
  const div1 = useRef<HTMLDivElement>(null);
  const div2 = useRef<HTMLDivElement>(null);
  const styles1 = {
    width: '100px',
    height: '100px',
    background: 'red',
    opacity: 0
  }
  const styles2 = {
    width: '100px',
    height: '100px',
    background: 'green',
    opacity: 0
  }
  // 使用 useEffect 实现动画效果
  useEffect(() => {
    if (div1.current) {
      div1.current.style.transition = 'opacity 3s';
      div1.current.style.opacity = '1';
    }
  }, []);

  // 使用 useLayoutEffect 实现动画效果
  useLayoutEffect(() => {
    if (div2.current) {
      div2.current.style.transition = 'opacity 3s';
      div2.current.style.opacity = '1';
    }
  }, []);

  return (
    <div>
      <div ref={div1} style={styles1}></div>
      <div ref={div2} style={styles2}></div>
    </div >
  );
}

效果:
测试和的执行方式

  • useEffect实现动画的元素有一个透明度渐变的效果。
  • useLayoutEffect实现动画的元素没有动画效果。

为什么?

我们都知道,CSS的动画在本质上就是某个CSS属性在数值上的变化。

  1. 使用useEffect实现的动画效果
    • 一开始透明度为0
    • 浏览器绘制完成
    • 异步执行useEffect,透明度变为1
    • 用户看到透明度从0->1的动画效果
  2. 使用useLayoutEffect实现的动画效果
    • 一开始透明度为0
    • DOM更新,同步执行useLayoutEffect,透明度变为1
    • 浏览器绘制完成
    • 由于绘制已经完成,透明度为1,用户看不到动画效果

希望这篇文章能帮助你更好地理解useLayoutEffect的使用方法,并为你的 React 项目带来更多的灵感和便利。
如果你有任何问题或建议,欢迎留言交流!


原文地址:https://blog.csdn.net/qq_46032105/article/details/145298468

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!