「React」useEffect 与 useLayoutEffect 使用与区别

前言

useEffect 与 useLayoutEffect 是两个 Hooks,前者比较常用,后者在一些场景下也会用到,下面说明两者区别和应用场景。
在这里插入图片描述

使用

useEffectuseLayoutEffect 是React Hooks里用于处理副作用的钩子(Hooks),它们看起来非常相似,但实际上在何时执行副作用上有细微差别,这影响到了它们的使用场景。

useEffect

useEffect 是在组件渲染到屏幕之后异步执行的。这意味着它不会阻塞浏览器的绘制过程,可以用于大多数副作用场景,比如数据获取、订阅或者手动修改DOM当组件更新后等。

  • 使用场景: 用于大部分没有严格的执行时序要求的副作用操作。
  • 执行时机: 在全部DOM变更完成后,浏览器绘制之后异步执行。
  • 影响: 因为是异步执行,不会阻塞页面的可视化渲染。

useLayoutEffect

useLayoutEffect 的执行时机更接近于类组件的 componentDidMountcomponentDidUpdate 生命周期方法。它在DOM更新完成后同步执行,但在浏览器进行绘制前。

  • 使用场景: 适用于需要同步调整布局的副作用操作。如果需要在DOM变化后立即同步执行一些操作(比如读取DOM布局并同步重绘),就可以用 useLayoutEffect
  • 执行时机: 在所有DOM变更之后同步执行,但在浏览器绘制之前。
  • 影响: 因为阻塞了浏览器的绘制,如果执行复杂或长时间运算,可能会导致性能问题或视觉上的卡顿。

区别

  • 执行时机: useEffect 是异步执行,不会阻塞浏览器的绘制;而 useLayoutEffect 是同步执行,在所有DOM变更之后立即运行,但这会延迟浏览器的绘制。
  • 适用场景: 一般推荐默认使用 useEffect,只有在涉及到需要在布局渲染阶段同步执行的DOM操作或有严格的顺序要求时,才使用 useLayoutEffect

由于 useLayoutEffect 会在绘制前执行,如果操作耗时过长,可能会导致用户感觉到卡顿。因此,除非必要,否则建议优先使用 useEffect

例子

当然可以。这里我会演示一个简单的例子,其中useLayoutEffectuseEffect将有不同的效果。

考虑以下场景:我们有一个要隐藏的消息,并且有一个按钮用于显示这个消息。如果我们使用useLayoutEffect去更改消息状态,用户界面不会显示任何隐藏-再显示的过渡效果,因为所有的更改都是在浏览器绘制之前发生的。相反,如果我们使用useEffect,那么可能会短暂看到消息从隐藏状态变为显示状态的过渡,因为useEffect是在组件渲染和浏览器绘制完成后才执行。

useLayoutEffect的行为

import React, { useLayoutEffect, useState } from 'react';

function LayoutEffectDemo() {
  const [message, setMessage] = useState('这是一条消息');
  const [hidden, setHidden] = useState(true);

  useLayoutEffect(() => {
    if (hidden) {
      setMessage('这是一条消息');
    }
  }, [hidden]);

  return (
    <div>
      {!hidden && <p>{message}</p>}
      <button onClick={() => setHidden(false)}>显示信息</button>
    </div>
  );
}

在这个例子中,“这是一条消息”将会在按钮点击后立即正确显示,用户不会看到任何视觉变化之前消息的状态。

useEffect的行为

现在,我们用相同的例子但用useEffect来替代useLayoutEffect

import React, { useEffect, useState } from 'react';

function EffectDemo() {
  const [message, setMessage] = useState('');
  const [hidden, setHidden] = useState(true);

  useEffect(() => {
    if (hidden) {
      setMessage('这是一条消息');
    }
  }, [hidden]);

  return (
    <div>
      {!hidden && <p>{message}</p>}
      <button onClick={() => setHidden(false)}>显示信息</button>
    </div>
  );
}

在使用useEffect的版本中,按钮点击后状态更新会导致组件的一个渲染周期,在这个周期中消息是隐藏的。然后useEffect会在这个渲染周期之后运行,并且消息会变成可见的。这个过程虽然非常快,但理论上可以被用户观察到,这就是为什么有的时候你会看到界面闪烁。

每一个钩子都有其用例,而显示不必要的用户界面变化(闪烁等)是应该避免的,通常是通过useLayoutEffect来处理,因为它在所有DOM变动之后同步执行,而且在浏览器进行绘制之前,从而保证用户看不到中间状态。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: useEffectuseLayoutEffect 都是 React Hooks,它们之间的主要区别在于当它们执行时发生的事情。useEffectReact 的每次渲染之后都会执行,而 useLayoutEffect 则会在 React 更新完 DOM 之后立即执行。 ### 回答2: useEffectuseLayoutEffectReact 中的两个钩子函数,它们的作用是在组件渲染完成后执行副作用操作。 区别主要体现在两个方面: 1. 调用时机: - useEffect 是在组件渲染完成后异步执行的,在浏览器的渲染完成后执行; - useLayoutEffect 在组件渲染完成后同步执行的,在浏览器的渲染之前执行。 2. 使用时机: - 当需要对 DOM 进行读取和修改操作时,应优先选择 useLayoutEffect。因为 useLayoutEffect 是在 DOM 渲染之前同步执行的,可以确保获取到准确的 DOM 布局信息。例如,在执行 useLayoutEffect 时,可以获得元素的准确尺寸和位置信息; - 当副作用操作不需要操作 DOM 时,或者可以放置于渲染完成后再执行的场景,可以选择 useEffect。因为 useEffect 是在浏览器渲染完成后异步执行的,不会阻塞页面的渲染过程。 总结: - 如果需要进行 DOM 的读取和修改操作,选择 useLayoutEffect; - 如果副作用操作不需要依赖于 DOM,而且可以延迟执行,选择 useEffect。 需要注意的是,尽量不要滥用 useLayoutEffect,因为它可能会影响页面的性能和用户体验。在大部分情况下,优先选择 useEffect,只有在确实需要获取准确 DOM 布局信息时,才使用 useLayoutEffect。 ### 回答3: useEffectuseLayoutEffect都是React中的副作用钩子,用于处理组件的副作用操作。它们的主要区别在于触发时机和阻塞渲染的能力。 useEffect是异步执行的副作用钩子,它会在组件渲染完成后延迟执行,不会阻塞渲染过程。useEffect的回调函数会在渲染阶段结束后,浏览器绘制完成之前执行。因此,它适合处理不会阻塞用户界面的副作用操作,比如数据获取、订阅事件等。 useLayoutEffectuseEffect的触发时机基本一致,但它是同步执行的副作用钩子。useLayoutEffect的回调函数会在组件渲染后同步执行,并在浏览器绘制之前结束。因此,如果在useLayoutEffect中进行一些修改DOM的操作,会在浏览器绘制之前生效,从而可以避免页面的闪烁等问题。 总结来说,useEffectuseLayoutEffect区别在于触发时机和阻塞渲染的能力。如果副作用操作不依赖于组件渲染的结果,并且不需要同步生效,可以使用useEffect;如果副作用操作需要在组件渲染后同步生效,可以使用useLayoutEffect

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zoe_ya

如果你成功申请,可以打赏杯奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值