不常用的Hooks之useLayoutEffect

文章介绍了ReactHooks中的useLayoutEffect,它在DOM变更后同步执行,用于处理需要立即同步更新的场景,以防止闪烁问题。然而,由于其可能阻塞渲染,建议尽量使用常规的useEffect。提供了一个示例展示了useLayoutEffect如何消除页面闪烁问题。
摘要由CSDN通过智能技术生成

不常用的Hooks之useLayoutEffect

useLayoutEffect的函数声明与useEffect相同,但是它会在所有的DOM变更之后同步调用effect。可以使用它来读取DOM布局并同步触发重新渲染。在浏览器执行绘制之前,useLayoutEffect内部的更新计划将被同步刷新。

尽可能使用标准的 useEffect 以避免阻塞视觉更新。

1. useEffect

useEffect基本使用

  • 默认情况下,都应该使用useEffectuseEffectcomponentDidMount、componentDidUpdate合并为同一个api

  • useEffect是异步的,所谓的异步就是利用requestIdleCallback,在浏览器空闲时间执行传入的callback

  • 大部分情况下,用哪一个都是一样的,如果副作用执行比较长,比如大量计算,如果是useLayoutEffect就会造成渲染阻塞。

2. useLayoutEffect

  • 这个是用在处理DOM的时候,当你的useEffect里面的操作需要处理DOM,并且会改变页面的样式,就需要用到它,否则可能会出现闪屏的问题,useLayoutEffect里面的callback函数会在DOM更新完成后立即执行,但是会在浏览器进行任何绘制之前运行完成,阻塞了浏览器的绘制。

  • 建议

    • useLayoutEffect需要在同步执行时使用,但是还是尽量别用,避免阻塞渲染

    • 在服务端SSR渲染的时候,最好放弃useLayoutEffect

3. 例子

  • 使用useEffect

    import React, { useEffect, useState, useLayoutEffect, useRef } from 'react';
    import { render } from 'react-dom';
    
    function App() {
      const [count, setCount] = useState(0);
      
      useEffect(() => {
        if (count === 0) {
          const randomNum = 10 + Math.random()*200
          setCount(10 + Math.random()*200);
        }
      }, [count]);
    
      return (
          <div onClick={() => setCount(0)}>{count}</div>
      );
    }
    
    render(<App />, document.getElementById('root'));
    
    • 当点击div的时候,页面会更新一串随机数。当你连续点击时,你会发现这串数字在发生抖动。

      原因在于,当你每次点击divcount会更新为0,之后useEffect内又把count改为一串随机数。

      所以页面会先渲染成0,然后再渲染成随机数,由于更新很快,所以出现了闪烁

  • 使用useLayoutEffect

    import React, { useEffect, useState, useLayoutEffect, useRef } from 'react';
    import { render } from 'react-dom';
    
    function App() {
      const [count, setCount] = useState(0);
      
      useLayoutEffect(() => {
        if (count === 0) {
          const randomNum = 10 + Math.random()*200
          setCount(10 + Math.random()*200);
        }
      }, [count]);
    
      return (
          <div onClick={() => setCount(0)}>{count}</div>
      );
    }
    
    render(<App />, document.getElementById('root'));
    
    • 和使用 useEffect相比,当你点击 divcount 更新为 0,此时页面并不会渲染,而是等待 useLayoutEffect 内部状态修改后,才会去更新页面,所以页面不会闪烁。
  • 在线试验

4. 总结

  • useLayoutEffect 相比 useEffect,通过同步执行状态更新可解决一些特性场景下的页面闪烁问题。

  • useEffect 可以满足大部分的场景,而且 useLayoutEffect 会阻塞渲染,因此谨慎使用。

参考:嗨,useLayoutEffect,醒醒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嘎嘎油

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值