分析一波 useEffect

2023-10-27

useEffect 介绍

useEffect是reactHook中最重要和常用的hook之一。对比React class 的生命周期函数,可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。

componentDidMount 挂载

componentDidUpdate 更新

componentWillUnmount 卸载

useEffect需要传递两个参数,第一个参数是逻辑处理函数,第二个参数是一个数组

useEffect(() => {

/** 执行逻辑 */

},[])

1

2

3

一、第二个参数存放变量,当数组存放变量发生改变时,第一个参数,逻辑处理函数将会被执行

二、第二个参数可以不传,不会报错,但浏览器会无线循环执行逻辑处理函数。

useEffect(() => {

/** 执行逻辑 */

})

1

2

3

三、第二个参数如果只传一个空数组,逻辑处理函数里面的逻辑只会在组件挂载时执行一次 , ~== componentDidMount

useEffect(() => {

/** 执行逻辑 */

},[])

1

2

3

四、第二个参数如果不为空数组,如下

const [a, setA] = useState(1);

const [b, setB] = useState(2);

useEffect(() => {

/** 执行逻辑 */

},[a,b])

1

2

3

4

5

逻辑处理函数会在组件挂载时执行一次和(a或者b变量在栈中的值发生改变时执行一次)  ~== componentDidMount +  componentDidUpdate 

五、useEffect第一个参数可以返回一个回调函数,这个回调函数将会在组件被摧毁之前和再一次触发更新时,将之前的副作用清除掉。~== componentWillUnmount。

useEffect去除副作用。我们可能会在组件即将被挂载的时候创建一些不断循环的订阅(计时器,或者递归循环)。在组件被摧毁之前,或者依赖数组的元素更新后,应该将这些订阅也给摧毁掉。

比如以下的情况(没有去除计时器,增大不必要的开销和代码风险)

const [time, setTime] = useState(0)

useEffect(() => {

const InterVal = setInterval(() => {

setTime(time + 1)

},1000)

},[])

1

2

3

4

5

6

7

利用第五点,在组件被摧毁前去除计时器。

const [time, setTime] = useState(0)

useEffect(() => {

const InterVal = setInterval(() => {

setTime(time + 1)

},1000)

return () => {

                   clearInterval(InterVal )

           }

},[])

1

2

3

4

5

6

7

8

9

10

useEffect常见坑

1、useEffect执行函数被循环执行。

没传第二个参数 ???

useEffect(() => {

/** 执行逻辑 */

})

1

2

3

解决的方法

useEffect(() => {

/** 执行逻辑 */

},[])

1

2

3

在useEffect执行函数里面改变了useEffect监测的变量 ???

const [a, setA] = useState(1);

useEffect(() => {

/** 执行逻辑 */

setA(a + 1)

},[a])

1

2

3

4

5

解决的方法 不要在useEffect第一参数执行函数中去改变第二参数依赖元素的地址的值。当依赖元素的地址的值发生改变,又会执行一次执行函数  === 无限循环。

2、useEffect监测不到依赖数组元素的变化。

依赖数组元素的地址的值没变?比如:

const [a, setA] = useState({

b: 'dx',

c: '18',

})

const changeA = () => {

setA((old) => {

old.b = 'yx'

return old

})

}

useEffect(() => {

/** 当组件挂载时执行一次changeA */

changeA ()

},[])

/**当changeA执行却没有打印 a*/

useEffect(() => {

/** 执行逻辑 */

console.log(a)

},[a])

1

2

3

... ...

21

22

是因为changeA没有真正的改变a在栈中的值(地址的值),只是改变了a在堆中的值。

useEffect监测不到堆中值得变化,所有引用类型数据都应该注意这一点。

解决的办法

const [a, setA] = useState({

b: 'dx',

c: '18',

})

const changeA = () => {

setA((old) => {

const newA = {...old}

newA .b = 'yx'

return newA

})

}

useEffect(() => {

/** 当组件挂载时执行一次changeA */

changeA ()

},[])

/**当changeA执行打印  {b:'yx',c:'18'}  */

useEffect(() => {

/** 执行逻辑 */

console.log(a)

},[a])

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分析一波 useEffect 的相关文章

随机推荐

  • linux 可执行文件反编译,如何反汇编,修改,然后重新组装一个Linux可执行文件?...

    我不认为有任何可靠的方法来做到这一点 机器码格式非常复杂 比assembly文件更复杂 编译的二进制文件 比如ELF格式文件 并不是真的有可能产生一个源代码汇编程序 它将编译成相同的 或类似的 二进制文件 为了理解差异 将GCC编译直接输出
  • linux命令之cal详解

    linux学习笔记之cal 在所有的类linux操作系统中 cal或者ncal命令会在命令行打印出一个有格式的日历 阳历 默认情况下 即不给定任何参数的情况下 cal和ncal将会输入本月的日历 并突出显示当前的日期 在Ubuntu22 0
  • 游戏王计算机兽,游戏王电脑堺卡牌——法王兽,吸血鬼谢里丹,龙龙,甲甲,凰凰...

    闇卡 真龙皇 法王兽 真龙皇 法 王 兽是真龙卡组的XYZ怪兽 也是真龙皇的boss卡 卡名带有真龙字段 种族为幻龙族 在设定上真龙皇与真龙互相敌对 幻龙族 超量 效果 9星怪兽 2只以上 1回合1次 把这张卡1个超量素材取除 宣言1个属性
  • leetcode55. 跳跃游戏

    给定一个非负整数数组 nums 你最初位于数组的 第一个下标 数组中的每个元素代表你在该位置可以跳跃的最大长度 判断你是否能够到达最后一个下标 示例 1 输入 nums 2 3 1 1 4 输出 true 解释 可以先跳 1 步 从下标 0
  • BackgroundWorker

    BackgroundWorker的事件响应函数 private void backgroundWorker1 DoWork object sender DoWorkEventArgs e BackgroundWorker worker se
  • VueCLI4.x+Vue2.x 使用postcss-px2rem和lib-flexible解决自适应问题 (解决组件样式被修改失效问题)

    简介 前端页面移动端免不了需要自适应高度宽度字体大小等等 如果直接写rem的话那会很麻烦 前端还需要根据设计图自己去转rem写样式 那样会非常麻烦且不易维护 本文将介绍前端写px像素单位自动转为rem单位 步骤 一 安装组件 npm ins
  • Spring Cloud-09-微服务统统一认证方案 Spring Cloud OAuth2 + JWT

    文章目录 微服务架构下统 认证场景 微服务架构下统 认证思路 OAuth2开放授权协议 标准 OAuth2介绍 OAuth2协议角色和流程 什么情况下需要使用OAuth2 OAuth2的颁发Token授权 式 Spring Cloud OA
  • 综合布线系统6个独立的子系统介绍

    综合布线系统是一个用于传输语音 数据 影像和其他信息的标准结构化布线系统 是建筑物或建筑群的传输网络 它使语言和数据通信设备 交换设备和其他信息管理系统彼此相连接 综合布线的热物理结构一般采用模块化设计和分层星型拓扑结构 系统结构有6个独立
  • ElasticSearch存储介绍

    基本概念介绍 node 节点 一个运行中的 Elasticsearch 实例称为一个节点 而集群是由一个或者多个拥有相同 cluster name 配置的节点组成 它们共同承担数据和负载的压力 当有节点加入集群中或者从集群中移除节点时 集群
  • HTML5 LocalStorage 本地存储

    原文地址 http www cnblogs com xiaowei0705 archive 2011 04 19 2021372 html 说到本地存储 这玩意真是历尽千辛万苦才走到HTML5这一步 之前的历史大概如下图所示 最早的Cook
  • python 区块链_区块链Python实现

    区块链是如同链表的一组记录 每个区块含有一些信息以及与其他区块关联的方法 每个区块有前一个区块的哈希值 时间戳 数据 class Block def init self timestamp data previous hash self t
  • 普通人怎么学习从语言

    C语言是一种非常重要的编程语言 它广泛用于操作系统 编译器 嵌入式系统 单片机等许多领域 通过学习C语言 您可以更好地理解计算机体系结构 掌握基本的编程技能 还可以进一步学习面向对象的语言和图形用户界面框架 从而开发出各种不同类型的软件和应
  • 数据结构与算法--KMP算法查找子字符串

    数据结构与算法 KMP算法查找子字符串 部分内容和图片来自这三篇文章 这篇文章 这篇文章 还有这篇他们写得非常棒 结合他们的解释和自己的理解 完成了本文 上一节介绍了暴力法查找子字符串 同时也发现了该算法效率并不高 当失配位置之前已经有若干
  • 一维熵局部熵C++实现

    基于OpenCV的一维熵与局部熵C 实现 由于要将MATLAB代码都转换为C 代码 因此开始了艰苦卓绝的码代码过程 这其中又遇到了很多的坑 以及爬坑过程 我的环境的是Visual studio2017 OpenCV3 本文内容 一维熵与局部
  • mybatis-plus--配置-(sql)日志输出-自动填充-分页-多数据源-逻辑删除-配置加密

    写在前面 本文主要介绍mybatis plus的配置 以后在有的时候在补充 欢迎交流 文章目录 日志输出 自动填充 分页 全局字段配置 多数据源 配置加密 日志输出 调试的时候需要看执行的sql 这时候就很需要日志来记录查看了 mybati
  • javaweb中spring出现parsing XML document from class path resource [applicationContext.xml]异常

    第一次在javaweb项目中使用spring可能会碰到下面的一个异常 严重 Context initialization failed org springframework beans factory BeanDefinitionStor
  • stm32控制esp8266的实现STA/AP/STa+AP程序

    一 引脚定义 ATK MW8266D模块的各个引脚的详细描述 如下表所示 一 功能说明 ATK MW8266D模块支持三种工作模式 分别为 STA AP STA AP STA模式 在此模式下 ATK MW8266D模块可连接其他设备提供的无
  • 概率论与数理统计 (二)填空题

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
  • qnx的触摸校准calib_校准工具使用教程

    锋影 email 174176320 qq com 环境配置 Hardware TI OMAPL138 Board OS QNX Neutrino 6 5 0 BSP bsp nto640 ti omap l138 evm trunk 20
  • 分析一波 useEffect

    useEffect 介绍 useEffect是reactHook中最重要和常用的hook之一 对比React class 的生命周期函数 可以把 useEffect Hook 看做 componentDidMount componentDi