react hooks--useLayoutEffect

news/2024/9/24 2:58:52/

概述

useLayoutEffect看起来和useEffect非常的相似,事实上他们也只有一点区别而已:

 useEffect会在渲染的内容更新到DOM上后执行,不会阻塞DOM的更新;

 useLayoutEffect会在渲染的内容更新到DOM上之前执行,会阻塞DOM的更新;

官方更推荐使用useEffect而不是useLayoutEffect。

如果我们希望在某些操作发生之后再更新DOM,那么应该将这个操作放到useLayoutEffect。

 

useLayoutEffect 的同步执行

useLayoutEffect 这个 hook 在执行的时候,也是先调用 destroy(),再执行 create()。和 useEffect 不同的是前者在 mutation 阶段执行,后者在 layout 阶段执行。与 useEffect 不同的是,它不用数组去存储销毁和创建函数,而是直接操作 fiber.updateQueue。

卸载上一次的 effect,发生在 mutation 阶段:

执行本次的 effect 创建,发生在 layout 阶段:

useEffect和useLayoutEffect作为组件的副作用,本质上是一样的。共用一套结构来存储effect链表。整体流程上都是先在render阶段,生成effect,并将它们拼接成链表,存到fiber.updateQueue上,最终带到commit阶段被处理。他们彼此的区别只是最终的执行时机不同,一个异步一个同步,这使得useEffect不会阻塞渲染,而useLayoutEffect会阻塞渲染。

演示示例

import React, { memo, useEffect, useLayoutEffect, useState } from 'react'const App = memo(() => {const [count, setCount] = useState(100)// useEffect(() => {//   console.log('useEffect执行了');//   // 这里的执行逻辑就是先赋值为0执行一遍,再设置值重新又执行一遍,就会出现闪烁的现象//   if(count === 0){//     setCount(Math.random() + 99)//   }// })useLayoutEffect(() => {console.log('useLayoutEffect执行了');// 这里就不会出现闪烁现象且执行一次if(count === 0){setCount(Math.random() + 99)}})return (<div><h4>count: {count}</h4><button onClick={e => setCount(0)}>设置为0</button></div>)
})export default App

总结

与 useEffect 的用法完全一样,作用也基本相同,唯一的不同在于执行时机,它会在所有的 DOM 变更之后同步调用 effect, 可以使用它来 useEffect 不会阻塞浏览器的绘制任务,它会在页面更新之后才执行。 而 useLayoutEffect 跟 componentDidMount 和 componentDidUpdate 的执行时机一样,会阻塞页面渲染,如果当中有耗时 任务的话,页面就会卡顿。大多数情况下 useEffect 比 class 的生命周期函数性能更好,我们应该优先使用它。 如果你正在将代码从 class 组件迁移到使用 Hook 的函数组件,则需要注意 useLayoutEffect与 componentDidMount、componentDidUpdate 的调用阶段是一样的。但是,我们推荐你一开始先用 useEffect,只有当它出问题的时候再尝试使用 useLayoutEffect。


http://www.ppmy.cn/news/1529614.html

相关文章

数据结构与算法-Trie树添加与搜索

trie树的使用场景 我们若需要制作一个通讯录的软件&#xff0c;使用常规树结构查询的复杂度为O(logn),但trie树的复杂度确与数据多少无关&#xff0c;与单词长度有关&#xff0c;这就大大缩减的查询的时间复杂度。 trie树的基本实现 基础结构 package com.study.trieDemo;i…

某恩加密数据爬虫逆向分析

目标网站 aHR0cHM6Ly93d3cuZW5kYXRhLmNvbS5jbi9pbmRleC5odG1s 一、抓包分析 响应数据加密 二、逆向分析 下断点&#xff0c;刷新页面 一直往下跟栈&#xff0c;发现是在这进行的加密 内部实现逻辑 本地数据获取 本文章仅提供技术分享交流学习&#xff0c;不可对目标服务器造…

【洛谷】AT_abc371_e [ABC371E] I Hate Sigma Problems 的题解

【洛谷】AT_abc371_e [ABC371E] I Hate Sigma Problems 的题解 洛谷传送门 AT传送门 题解 I Hate Sigma Problems!!! 意思很简单就是求序列中每一个子区间内含有不同数字的个数之和。 暴力的话时间复杂度是 O ( n 2 ) O(n ^ 2) O(n2)&#xff0c;是肯定不行的&#xff0…

DSP学习00-F28379D学习准备(了解一个工程的构成)

叠甲 我也算初学F28379D&#xff0c;不对之处请大家斧正。不同型号的DSP在外设配置的函数上有一些区别&#xff0c;但是掌握一种对其他型号的来说则难度不大。对于我们而言学习DSP最终还是要用于算法验证&#xff0c;而DSP资源的最大化利用、代码效率提升等则是后话。 软件准…

macOS使用brew安装并配置python环境

1.确认已安装brew环境,如没有安装,参考: macOS系统Homebrew工具安装及使用-CSDN博客 2.安装python python安装成功 3.添加pip路径到/etc/paths 4.查看python与pip默认安装版本

Django 创建好的模块怎么在后台显示

1、配置模型及其需要显示的数据 刚才创建好的tests的增删改查&#xff0c;在后台是不显示的&#xff0c;所以需要进行配置,在刚才创建好的模块里找到admin.py文件&#xff0c;在里面进行如下配置 from django.contrib import adminfrom . import models from .models import …

新能源汽车数据大全(产销数据\充电桩\专利等)

新能源汽车数据大全&#xff08;产销数据\充电桩\专利等&#xff09; 来源&#xff1a;全国各省市统计年鉴、统计公报、国家能源署、中国汽车行业协会&#xff0c;各类汽车统计年鉴、中国电动汽车充电基础设施促进联盟等 1、汽车分品牌产销(95家车企&#xff0c;768个车型&am…

Spring Boot-依赖冲突问题

Spring Boot 依赖冲突问题及其解决方案 1. 引言 在Spring Boot项目中&#xff0c;依赖管理是一个至关重要的环节。Spring Boot通过自动配置和强大的依赖管理简化了应用开发&#xff0c;但随着项目规模扩大和依赖数量的增加&#xff0c;依赖冲突问题常常会浮现。依赖冲突不仅会…