React Hooks —— useLayoutEffect及其与useEffect的区别

文章详细阐述了useLayoutEffect和useEffect在React应用中的不同作用。useLayoutEffect在所有DOM变更后同步调用,常用于同步更新布局并防止视觉闪烁,而useEffect则在浏览器绘制之后异步执行,可能引起闪烁。两者的区别在于是否阻塞浏览器的渲染过程,以及对界面更新的影响。
摘要由CSDN通过智能技术生成

useLayoutEffect

使用

useLayoutEffect函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用effect。

可以使用它来读取 DOM 布局并同步触发重渲染。

在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

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

import React, { useState, useEffect, useLayoutEffect } from "react";
export default function Demo() {
    let [num, setNum] = useState(0);
    // 再试试useLayoutEffect
    useEffect(() => {
        if (num === 0) {
            let random = +String(Math.random()).substring(2);
            setNum(random);
        }
    }, [num]);
    return <div
        style={{
            background: 'lightblue',
            WebkitUserSelect: "none"
        }}
        onClick={() => {
            setNum(0);
        }}>
        {num}
    </div>;
};

useEffect和useLayoutEffect区别

useLayoutEffect会阻塞浏览器渲染真实DOM【真实DOM对象已经创建了】,优先执行Effect链表中的callback;

useEffect不会阻塞浏览器渲染真实DOM,在渲染真实DOM的同时,去执行Effect链表中的callback

  • 它们里面的回调函数都是放在effect链表中的,但是useLayoutEffect设置的callback要优先于useEffect去执行
  • 在两者设置的callback中,依然可以获取DOM元素「原因:真实DOM对象已经创建了,区别只是浏览器是否渲染」
  • 如果在callback函数中又修改了状态值「视图又要更新」
    • useEffect:浏览器肯定是把第一次的真实已经绘制了,再去渲染第二次真实DOM【频繁切换有闪烁】
    • useLayoutEffect:浏览器是把两次真实DOM的渲染,合并在一起渲染的【频繁切换无闪烁】

视图更新周期:

第一步:基于babel-preset-react-app把JSX编译为createElement格式

第二步:执行createElement(…)方法,创建出virtualDOM

第三步:基于root.render方法把virtualDOM变为真实DOM对象「DOM-DIFF」

  • useLayoutEffect阻塞浏览器绘制:在整个视图渲染更新周期中,创建出真实DOM以后直接执行useLayoutEffect的effect链表中的方法。如果该方法有setXXX操作,那么会直接进入下一次更新周期中,而不会执行第四步。因此无论视图更新的过程执行了多少次,界面永远只看到了一次变化,即【频繁切换无闪烁】

  • useEffect不阻塞浏览器绘制:在React渲染完真实DOM之后、浏览器绘制完毕之前会执行effect链表中的方法,同时第四步也会异步执行。如果effect链表中的方法有setXXX操作,那么会直接进入下一次更新周期中,同时上一次更新周期中的第四步还在执行,浏览器还在重绘。如果在useEffect中频繁触发更新,后台会异步运行多个“第四步”,由于浏览器绘制是需要一定时间的,因此对于速度较慢的设备,用户会看到多次重绘之间的“白屏”,即【频繁切换有闪烁】

第四步:浏览器渲染和绘制真实DOM对象

从视图更新周期可以看出,useLayoutEffect和useEffect都是可以获取真实DOM的时机

官方文档示例参考

https://react.docschina.org/reference/react/useLayoutEffect#usage

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值