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

react hooks--useLayoutEffect

概述

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.kler.cn/a/313970.html

相关文章:

  • 微服务架构面试内容整理-API 网关-Gateway
  • 【C#设计模式(8)——过滤器模式(Adapter Pattern)】
  • 闯关leetcode——3174. Clear Digits
  • 【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
  • Systemd: disable和mask的区别
  • 测试实项中的偶必现难测bug--验证码问题
  • oracle 11g SYSAUX表空间清理
  • 微服务——网关登录校验(一)
  • ODrive电机驱动算法VScode环境配置笔记教程
  • Java | Leetcode Java题解之第412题Fizz Buzz
  • Apache doris手动部署时报错“Please disable swap memory before installation.“
  • Web 服务器介绍 | 通过 Tomcat 说明其作用
  • 华为摄像机/NVR主动注册协议接入SVMSP平台
  • pytorch入门(2)——TensorBoard的使用
  • Python利用PyInstaller封装EXE文件
  • 2024“华为杯”中国研究生数学建模竞赛(E题)深度剖析_数学建模完整过程+详细思路+代码全解析
  • Mysql实战
  • RNN的反向传播
  • 经典sql题(九)SQL 查询详细指南总结二
  • MySQL中的LIMIT与ORDER BY关键字详解
  • git 推送文件
  • vue3 ant-design 4.x 表格动态行样式设置
  • Tomcat服务器—Windows下载配置详细教程
  • Sui Builder House锦集,原生USDC和CCTP即将登陆Sui
  • 【HTTP】请求“报头”,Referer 和 Cookie
  • (CS231n课程笔记)深度学习之损失函数详解(SVM loss,Softmax,熵,交叉熵,KL散度)