当前位置: 首页 > article >正文

React 第十九节 useLayoutEffect 用途使用技巧注意事项详解

1、概述

useLayoutEffectuseEffect 的一个衍生版本,只是他们的执行时机不同

useLayoutEffect 用于在DOM更新执行完成之后浏览器渲染绘制之前执行,这会阻塞浏览器的渲染;
useEffect 的执行时机是在组件首次渲染和更新渲染之后异步执行的,这就意味着 useEffect 的执行并不会阻塞组件的渲染,也不会影响到用户的交互体验;

由于useEffect 执行的的异步操作,那么在其副作用函数中执行,数据请求DOM操作定时任务,即使有大量的计算耗时,也不会让用户感觉到界面卡顿现象
useLayoutEffect 执行的是同步操作,不适用于大量耗时的进程在副作用函数中执行,否则会是界面显的非常卡顿,从而影响用户的体验感;

useEffect具体使用详情

2、写法

useLayoutEffect(setup, dependencies)

第一个参数setup,处理副作用的函数,在将组件首次添加到 DOM 之前,React 将运行 setup 函数。在每次因为依赖项变更而重新渲染后,React 将首先使用旧值运行 cleanup 函数(如果你提供了该函数),然后使用新值运行 setup 函数。在组件从 DOM 中移除之前,React 将最后一次运行 cleanup 函数。
第二个参数:依赖项数组,与 useEffect的依赖项一样为可选项;

useLayoutEffect(() => {
    console.log('=设置函数==')
    // 用于根据依赖项变化而执行的逻辑
    return () => {
        // 清理函数,组件卸载移除时,执行的逻辑
    }
},[name])

3、用法示例

当我们使用 useEffect 将一个圆形由直径 10px,变大到 直径为200px时;会看到 图形的变化整个过程
而我们使用 useLayoutEffect 时,直接看到的就是 直接为 200px 的圆形,不会看到图片变化过程,给用户的感觉视图的白屏时间更长,体验不好;

/* index.less文件 */
.base-class{
    display: block;
    width: 10px;
    height: 10px;
    background-color: #f00;
    border-radius: 50%;
    position:relative;
}
.area-box{
    width: 200px;
    height: 200px;
}
3.1 使用 useEffect Hook时,

异步执行,不会阻塞浏览器渲染,故可以看见图形变化过程;

import {useState, useEffect } from 'react'
import './index.less'


export default function MyLayoutEffect() {
    const [area, setArea] = useState(false)
    const handleChangeArea = () => {
        setArea(false)
    }
    // 使用时间延迟
    let now = performance.now()
    while (performance.now() - now < 200) {}
    useEffect(() => {
        setArea(true)
    }, [area])
  return (
    <div>
        <span className={area ? 'base-class area-box' : 'base-class'}>useEffect圆的面积</span>
        <hr />
        <p>areaLayout:---{areaLayout}----</p>
        <hr />  
        <button onClick={handleChangeArea}>改变圆形面积</button>
    </div>
  )
}

3.2、使用 useLayoutEffect 时,

无论我们是点击按钮改变原型大小,还是初次加载,屏幕中始终的 直径为 200px 的圆形;这是因为 useLayoutEffect 的状态更新,会在屏幕渲染之前执行,进而导致阻塞渲染,而一直看到都是大图

import {useState, useLayoutEffect} from 'react'
import './index.less'


export default function MyLayoutEffect() {

    const [areaLayout, setAreaLayout] = useState(false)
    const handleChangeArea = () => {
        setAreaLayout(false)
    }
    let now = performance.now()
    while (performance.now() - now < 200) {}

    useLayoutEffect(() => {
        setAreaLayout(true)
    }, [areaLayout])

  return (
    <div>

        <p>areaLayout:---{areaLayout}----</p>
        <span className={areaLayout ? 'base-class area-box' : 'base-class'}>useLayoutEffect</span>
        <hr />  
        <hr />
        <button onClick={handleChangeArea}>改变圆形面积</button>
    </div>
  )
}

4、使用场景

1、需要在屏幕渲染完成之前 获取元素DOM位置尺寸,同步进行调整
2、防止闪屏,因useLayoutEffect 会在浏览器渲染前计算好 元素的位置大小,故不会像 useEffect,会看见视图元素 位置大小变化过程,但是如果时间过短,会给用户一种闪屏错觉


http://www.kler.cn/a/451189.html

相关文章:

  • 打造高效的 LaTeX 公式编辑器
  • 在跨平台开发环境中构建高效的C++项目:从基础到最佳实践20241225
  • 14:30面试,14:08就出来了,面试问的有点变态呀。。。
  • Idea导入Springboot项目,无法正确加载yml文件,且不为绿色图标的解决办法
  • LeetCode 844. 比较含退格的字符串 (C++实现)
  • Docker 部署 plumelog 最新版本 实现日志采集
  • 大语言模型中的Agent优势及相关技术;Agent和RAG区别
  • 对BG兼并点的理解-不断刷新版
  • golangci-lint安装与Goland集成
  • 《算法》题目
  • 13. 导出与导入镜像
  • 边缘计算收益稳定
  • 信息安全技术——物理环境与设备安全、虚拟专用网
  • 【YashanDB知识库】XMLAGG方法的兼容
  • DevExpress WPF中文教程:Grid - 如何移动和调整列大小?(二)
  • Refusal in Language Models Is Mediated by a Single Direction
  • GESP CCF C++五级编程等级考试认证真题 2024年12月
  • 第20天:JS信息收集-Web应用JS架构URL提取数据匹配Fuzz接口WebPack分析自动化
  • springboot-starter版本升级es版本问题
  • 目标检测——基于yolov8和pyqt的螺栓松动检测系统
  • Spark和MapReduce之间的区别?
  • HTML5适配手机
  • GamePlay UE网络同步
  • 基于Java的智能客服系统
  • uniapp开发微信小程序实现获取“我的位置”
  • TCP Vegas拥塞控制算法——baseRtt 和 minRtt的区别