React-Hooks-useLayoutEffect

简介: React-Hooks-useLayoutEffect

useLayoutEffect Hook 概述


  • 大部分情况下 useLayoutEffect 和 useEffect 没太大区别(用法格式都相同)
  • 但是如果需要修改 DOM 的布局样式, 那么推荐使用 useLayoutEffect

为什么推荐在 useLayoutEffect 中修改 DOM 的布局样式?


  • useEffect 函数会在组件渲染到屏幕之后才执行, 所以会可能会出现 闪屏 的情况
  • useLayoutEffect 函数是在组件渲染到屏幕之前执行, 所以不会出现闪屏情况

首先来看 useEffect 会出现闪屏的情况代码如下:


App.js:

import React, {useRef, useState, useEffect} from 'react';
import './app.css'
function Home() {
    const pRef = useRef();
    useEffect(() => {
        console.log('组件被挂载或更新完成 - useEffect');
        pRef.current.style.left = '0px';
        pRef.current.style.left = '500px';
        return () => {
            console.log('组件即将被卸载 - useEffect');
        }
    });
    return (
        <div>
            <p ref={pRef}></p>
        </div>
    )
}
export default function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            <button onClick={() => {
                setShow(!show)
            }}>切换
            </button>
        </div>
    )
}


如上代码大致意思就是通过一个按钮来控制 Hmoe 组件的显示与隐藏。

app.css:

p {
    width: 100px;
    height: 100px;
    position: relative;
    left: 0;
    top: 0;
    background: red;
}


运行项目然后点击切换按钮,你会发现在切换的过程当中会有一闪而过的效果这就是所谓的闪屏。

在来看 useLayoutEffect 的效果代码如下:

import React, {useRef, useState, useLayoutEffect} from 'react';
import './app.css'
function Home() {
    const pRef = useRef();
    useLayoutEffect(() => {
        console.log('组件被挂载或更新完成 - useLayoutEffect');
        pRef.current.style.left = '0px';
        pRef.current.style.left = '500px';
        return () => {
            console.log('组件即将被卸载 - useLayoutEffect');
        }
    });
    return (
        <div>
            <p ref={pRef}></p>
        </div>
    )
}
export default function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            <button onClick={() => {
                setShow(!show)
            }}>切换
            </button>
        </div>
    )
}


可以很清晰的发现,两者的效果是完全不同的。



useEffect 和 useLayoutEffect 的区别


执行时机不同:

  • 如果是挂载或者更新组件, 那么 useLayoutEffect 会比 useEffect 先执行
import React, {useRef, useState, useEffect, useLayoutEffect} from 'react';
import './app.css'
function Home() {
    const pRef = useRef();
    useEffect(() => {
        console.log('组件被挂载或更新完成 - useEffect');
        return () => {
            console.log('组件即将被卸载 - useEffect');
        }
    });
    useLayoutEffect(() => {
        console.log('组件被挂载或更新完成 - useLayoutEffect');
        return () => {
            console.log('组件即将被卸载 - useLayoutEffect');
        }
    });
    return (
        <div>
            <p ref={pRef}></p>
        </div>
    )
}
export default function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            <button onClick={() => {
                setShow(!show)
            }}>切换
            </button>
        </div>
    )
}

  • 如果是卸载组件, 那么 useEffect 会比 useLayoutEffect 先执行

  • useEffect: 同步
  • useLayoutEffect: 异步




什么时候使用 useEffect


  • 在绝大多数的情况下能用 useEffect, 就用 useEffect

什么时候用 useLayoutEffect


  • 只有在需要组件挂载之后更新 DOM 的布局和样式的时候才使用 useLayoutEffect

为什么要使用 useLayoutEffect 来更新 DOM 布局和样式


useEffect 是组件已经渲染到屏幕上了才执行,useLayoutEffect 是组件还没有渲染到屏幕上就会执行,所以如果在组件已经渲染到屏幕上了, 才去更新 DOM 的布局和样式, 那么用户体验不好, 会看到闪屏的情况,而如果是在组件还没有渲染到屏幕上, 就去更新 DOM 的布局和样式, 那么用户体验更好, 看不到闪屏情况。



最后

本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
jenkins 测试技术 应用服务中间件
【专业测试技能】全流程掌握:部署测试环境的策略与实践
本文分享了关于部署测试环境的策略与实践。文章讨论了部署测试环境的全过程,包括服务如MySQL、Redis、Zookeeper等的部署,以及解决服务间的依赖和兼容问题。文中还介绍了使用Jenkins、Docker等工具进行部署的方法,并通过实战案例讲解了如何创建和管理Jenkins Job、配置代理服务器Nginx、进行前后端服务的访问和优化。最后,作者强调了提问的重要性,并鼓励大家通过互联网解决遇到的问题。
394 2
【专业测试技能】全流程掌握:部署测试环境的策略与实践
|
缓存 Docker 容器
50-Docker-多阶段构建和镜像瘦身
50-Docker-多阶段构建和镜像瘦身
|
10月前
|
Java 程序员 API
Java循环操作哪个快?
本文探讨了Java中stream API与传统for循环在性能上的对比,通过多个示例分析了不同场景下两者的优劣。作者指出,尽管stream API使代码更简洁,但不当使用会降低可读性和性能,特别是在处理大数据量时。实验结果显示,在多数情况下,普通for循环的性能优于stream API,尤其是在单次操作耗时较短但需多次执行的场景中。文章建议开发者在设计初期就考虑全局流程,避免重复使用stream流,以提升代码质量和性能。
232 1
Java循环操作哪个快?
|
人工智能 物联网 测试技术
使用PAI×LLaMA Factory 微调 Llama3 模型
本次教程介绍了如何使用PAI和LLaMA Factory框架,基于轻量化LoRA方法微调Llama-3模型,使其能够进行中文问答和角色扮演,同时通过验证集ROUGE分数和人工测试验证了微调的效果。在后续实践中,可以使用实际业务数据集,对模型进行微调,得到能够解决实际业务场景问题的本地领域大模型。
使用PAI×LLaMA Factory 微调 Llama3 模型
|
设计模式 人工智能 安全
【Tomcat源码分析】生命周期机制 Lifecycle
Tomcat内部通过各种组件协同工作,构建了一个复杂的Web服务器架构。其中,`Lifecycle`机制作为核心,管理组件从创建到销毁的整个生命周期。本文详细解析了Lifecycle的工作原理及其方法,如初始化、启动、停止和销毁等关键步骤,并展示了LifecycleBase类如何通过状态机和模板模式实现这一过程。通过深入理解Lifecycle,我们可以更好地掌握组件生命周期管理,提升系统设计能力。欢迎关注【码上遇见你】获取更多信息,或搜索【AI贝塔】体验免费的Chat GPT。希望本章内容对你有所帮助。
|
小程序
微信小程序实现不同按钮跳转同一个页面显示不同内容
微信小程序实现不同按钮跳转同一个页面显示不同内容
277 0
|
关系型数据库 MySQL 数据库
探究数据库开源协议:PostgreSQL vs MySQL
探究数据库开源协议:PostgreSQL vs MySQL
|
开发框架 移动开发 JavaScript
SpringCloud微服务实战——搭建企业级开发框架(四十六):【移动开发】整合uni-app搭建移动端快速开发框架-环境搭建
正如优秀的软件设计一样,uni-app把一些移动端常用的功能做成了独立的服务或者插件,我们在使用的时候只需要选择使用即可。但是在使用这些服务或者插件时一定要区分其提供的各种服务和插件的使用场景,例如其提供的【uni-starter快速开发项目模版】几乎集成了移动端所需的所有基础功能,使用非常方便,但是其许可协议只允许对接其uniCloud的JS开发服务端,不允许对接自己的php、java等其他后台系统。
497 61
|
Java 程序员 数据处理
从软件危机中处理软件工程问题
【6月更文挑战第28天】本文介绍软件危机及其处理方式。1968年的北约会议首次提出“软件危机”,指软件开发的复杂性和成本超支问题。现代解决策略包括多种方法和模型,如OO、结构化、RUP和SOA,旨在提高效率和适应性。
1067 0
从软件危机中处理软件工程问题
|
前端开发
如何使用FabricJS创建带有文本光标的画布?
在FabricJS中创建带文本光标的画布涉及使用fabric.IText类模拟光标效果。示例代码展示如何创建Canvas,添加IText对象,并通过Rect对象模拟光标。当文本对象变化时,更新光标位置,并监听键盘事件以处理光标移动。请注意,此示例仅用于基础演示,实现全功能文本编辑器可能需要额外的逻辑和工具。