【前端知识】React 基础巩固(四十三)——Effect Hook

news2024/11/15 19:38:51

React 基础巩固(四十三)——Effect Hook

一、Effect Hook的基本使用

Effect Hook 用来完成一些类似class中生命周期的功能。

在使用类组件时,不管是渲染、网路请求还是操作DOM,其逻辑和代码是杂糅在一起的。例如我们希望把计数器结果显示在标签上,在类组件中,我们通过生命周期进行实现,如下所示:

import React, { PureComponent } from "react";

export class App extends PureComponent {
  constructor() {
    super();

    this.state = {
      counter: 100,
    };
  }

  componentDidMount() {
    document.title = this.state.counter;
  }

  componentDidUpdate() {
    document.title = this.state.counter;
  }

  render() {
    const { counter } = this.state;
    return (
      <div>
        <h2>计数:{counter}</h2>
        <button onClick={(e) => this.setState({ counter: counter + 1 })}>
          +1
        </button>
      </div>
    );
  }
}

export default App;

在函数组件中,我们可以利用useEffect来完成除渲染界面以外的事情,即完成副作用的事情。这样能让代码和逻辑看起来更清晰、简洁:

import React, { memo, useEffect, useState } from "react";

export default memo(function App() {
  const [count, setCount] = useState(200);

  // 完成一些除渲染外,副作用的事情
  useEffect(() => {
    // 当前传入的回调函数会在组件被渲染完成后,自动执行
    // 网络请求/DOM操作/事件监听
    document.title = count;
  });

  return (
    <div>
      <h2>计数:{count}</h2>
      <button onClick={(e) => setCount(count + 1)}>+1</button>
    </div>
  );
});

可以看到,通过useEffect的Hook,能够告知react在渲染后需要执行哪些操作。在react执行完更新DOM操作后,会回调我们在useEffect中传入的回调函数。在默认情况下,这个函数无论是第一次渲染还是每次更新后,均会被调用。

二、需要清除的Effect

在class组件中,我们通常会在componentDidMount中设置监听事件,componentWillUnmount中清除监听事件;而利用useEffect的函数组件中,我们可以通过useEffect的返回值(回调函数)来实现事件监听的清除操作:

import React, { memo, useEffect, useState } from "react";

export default memo(function App_clear() {
  const [count, setCount] = useState(0);

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    // 监听事件
    // const unsubscribe = store.subscribe(() => {});

    // function foo() {}
    // eventBus.on("test", foo);

    // 监听和取消放在一个地方,内聚性高
    console.log("假设监听unsubscribe、eventBus等事件");

    // // 返回值:回调函数 => 组件重新渲染或组件卸载时执行
    return () => {
      console.log("取消监听unsubscribe、eventBus等事件");
    };
  });

  return (
    <div>
      <button onClick={(e) => setCount(count + 1)}>+1({count})</button>
    </div>
  );
});

useEffect中返回的函数,是effect的可选的清除机制,能够实现将设置监听和取消监听的逻辑放在一起,提高内聚性。

image-20230731214407030

三、多个Effect的使用

假设我们在useEffect执行如下三个操作:

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    // 1.修改document的title

    // 2.对redux中数据变量的监听

    // 3.监听eventBus中的事件
  });

我们会发现,随着事件的增多,useEffect中的逻辑会逐渐复杂,这时我们可以将其拆分为多个effect,依次执行,即react支持多个useEffect:

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    // 1.修改document的title
    console.log('1.修改document的title');
  });

  useEffect(() => {
    // 2.对redux中数据变量的监听
    console.log('2.对redux中数据变量的监听');
  });

  useEffect(() => {
    // 3.监听eventBus中的事件
    console.log('3.监听eventBus中的事件');
  });

当我们每次触发页面渲染后,可以看到,三个事件被依次执行:

image-20230731215518004

四、Effect的执行机制

我们发现,每次点击按钮都会执行监听操作,假设effect中是一个网络请求事件,则会在每次更新后发起请求,这样频繁的监听、请求绝对不是我们想要的。我们可以用useEffect的第二个参数来控制其执行机制:

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    // 1.修改document的title
    console.log("1.修改document的title");
  }, [count]);

  useEffect(() => {
    // 2.对redux中数据变量的监听
    console.log("2.对redux中数据变量的监听");
  }, []);

  useEffect(() => {
    // 3.监听eventBus中的事件
    console.log("3.监听eventBus中的事件");
  }, []);

当我们传入一个空数组时,意味着该副作用事件不依赖任何内容,此时与componentDidMount的效果一致,只有在第一次加载时,才会执行useEffect:

image-20230731220520078

当我们对于事件1传入[count]时,则意味着事件1所在的useEffect依赖count变量,当count变量发生变化时,则会执行。于是,当我们点击按钮修改count值时,只有事件1会被一次次的触发:

image-20230731220704060

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/817614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CRM系统如何进行公海池线索分配自动化?

在销售过程中&#xff0c;线索分配是一个非常重要的环节。传统的线索分配方式往往是由销售主管手动进行&#xff0c;不仅效率低下&#xff0c;还存在着不公平、不灵活的问题。因此&#xff0c;许多企业通过CRM来实现公海池线索分配自动化。 1、基于规则的分配 CRM可以让用户设…

docker push 报错:unauthorized: unauthorized to access repository: library/xx处理方法

rootmaster:/home/data/harbor# sudo docker login 49.0.241.2 admin Harbor12345 1.报错原因分析 rootmaster:/home/data/harbor# docker push 49.0.241.2/library/nginx:latest #这种报错 The push refers to repository [49.0.241.2/library/nginx] Get "https://49.…

windows自动化点击大麦app抢购、捡漏,仅支持windows11操作系统

文章目录 必要条件程序运行必要条件 确保windows11版本操作系统,如果不是可以通过镜像升级为windows11如果已经是windows11操作系统,确保更新到最新版本 修改系统所在时区,将国家或地区改为美国 开启虚拟化 勾选Hyper-V,如果没有则不需要勾选 勾选虚拟机平台 勾选完毕,点…

pytest固件fixture不同层级作用域如何调用

之前的一篇文章中讲解了fixture结合conftest.py文件如何简单实现自动化。实际fixture结合conftest.py文件的使用就是一种fixture的会话层级session的实战用法。 下面开始fixture其他层级的详细讲解&#xff1a; 1、首先在使用fixture之前我们得先了解他是干什么的&#xff0c…

python_PyQt5开发验证K线视觉想法工具V1.1 _增加标记类型_线段

目录 运行情况&#xff1a; 代码&#xff1a; 承接 【python_PyQt5开发验证K线视觉想法工具V1.0】 博文 https://blog.csdn.net/m0_37967652/article/details/131966298 运行情况&#xff1a; 添加线段数据在K线图中用线段绘制出来 代码&#xff1a; 1 线段标记的数据格式…

M1中安装PD18.3.2

1.下载 在添加链接描述中直接搜索Paralles Desktop 点击右下角的免费下载(Z10 MB) 点击安装说明中的第一个选项直接下载链接 安装说明中第一条强调了必须关闭SIP 点击右上角的下载文件 下载后 2.双击解压文件 3.点击解压后的映像文件 4.点击安装&#xff0c;再次点击打开…

【嵌入式学习笔记】嵌入式基础7——认识HAL库

1.初识HAL库 1.1.CMSIS CMSIS (微控制器软件接口标准)&#xff1a;Cortex Microcontroller Software Interface Standard&#xff0c;是由ARM和与其合作的芯片厂商、软件工具厂商&#xff0c;共同制定的标准。 1.2.HAL库简介 直接操作寄存器&#xff1a;执行效率高&#x…

JVM基础篇-本地方法栈与堆

JVM基础篇-本地方法栈与堆 本地方法栈 什么是本地方法? 本地方法即那些不是由java层面实现的方法&#xff0c;而是由c/c实现交给java层面进行调用&#xff0c;这些方法在java中使用native关键字标识 public native int hashCode()本地方法栈的作用? 为本地方法提供内存空…

Vue中默认插槽,具名插槽,作用域插槽区别详解

默认插槽&#xff1a; App.vue : 在app.vue中使用MyCategory&#xff0c;里面包裹的结构是不显示的&#xff0c;要想在页面中显示&#xff0c;就需要用到插槽。在子组件MyCategory中定义 <template><div class"container"><MyCategory title"美…

号称永不限速的它抛弃初心,网盘界从此再无净土

自从百度网盘一家独大&#xff0c;带来免费用户 KB/s 级下载体验后&#xff0c;小忆一直在期待一款免费不限速网盘。 直到阿里云盘的出现可算是满足了小忆对网盘的所有期许。 新用户初始免费容量尽管只有 100G&#xff0c;但当初通过几个简单小任务就能轻松提升至数 TB。 最重…

渗透测试:Linux提权精讲(二)之sudo方法第二期

目录 写在开头 sudo expect sudo fail2ban sudo find sudo flock sudo ftp sudo gcc sudo gdb sudo git sudo gzip/gunzip sudo iftop sudo hping3 sudo java 总结与思考 写在开头 本文在上一篇博客的基础上继续讲解渗透测试的sudo提权方法。相关内容的介绍与背…

RISC-V公测平台发布 · 如何在SG2042上玩转k3s

前言 Kubernetes是一个开源的容器管理平台&#xff0c;通过Kubernetes的跨集群管理功能&#xff0c;用户可以方便地进行应用程序的复制、迁移和跨云平台的部署。 而k3s作为Kubernetes的轻量级发行版&#xff0c;相比传统的Kubernetes具有更小的二进制文件大小和更低的资源消耗…

在简历上写了“精通”后,拥有工作经验的我被面试官问到窒息

前言 如果有真才实学&#xff0c;写个精通可以让面试官眼前一亮&#xff01; 如果是瞎写&#xff1f;基本就要被狠狠地虐一把里&#xff01; 最近在面试&#xff0c;我现在十分后悔在简历上写了“精通”二字… 先给大家看看我简历上的技能列表&#xff1a; 熟悉软件测试理论基…

数据存储需求骤变,联想凌拓多招齐发推动数以致用

有人说&#xff0c;数据存储决定着未来数字化转型的深度。深以为然。 今年以来&#xff0c;千行百业的用户们愈发意识到数据存储的重要性。无论是席卷全球的生成式AI浪潮&#xff0c;需要存储“投喂”各种非结构化数据&#xff1b;还是多云环境下&#xff0c;用户们对于数据自…

ODIN_1靶机详解

ODIN_1靶机复盘 下载地址&#xff1a;https: //download.vulnhub.com/odin/odin.ova 靶场很简单&#xff0c;一会儿就打完了。 靶场说明里提醒说加一个dns解析。 我们在/etc/hosts加一条解析 就能正常打开网站了&#xff0c;要么网站打开css是乱的。 这里看到结尾就猜测肯定…

全网最全讲的最详细的多线程原理

在我们开始讲多线程之前&#xff0c;我们先来了解一下什么是进程&#xff0c;什么是线程。进程和线程是操作系统中两个容易混淆的概念。 进程 在Windows操作系统中打开任务管理器&#xff0c;可以查看进程和线程的详细信息。也可以使用专业的进程查看小软件——Process Explo…

适合做笔记的软件有哪些?8款好用强大的笔记软件推荐!

除了Goodnotes和Notability&#xff0c;你还知道哪些值得推荐的免费笔记软件吗&#xff1f;本文结合自己的使用经验&#xff0c;推荐笔记软件的同时&#xff0c;亦推荐一些不错的绘图软件供大家选择使用。 1.OneNote 基本的笔记功能都有&#xff0c;加粗、倾斜、下划线、突…

【RL】我的强化学习代理

一、说明 强化学习代理是一个自主决策的人工智能智能系统&#xff0c;它通过与环境进行交互&#xff0c;通过试错学习&#xff0c;逐步优化其行为以实现其目标。这种代理能够学习如何在环境中进行行为&#xff0c;以实现预期的目标。代理可以通过尝试不同的行为来评估其对环境的…

1.2.2最长上升子序列模型(二)

1.拦截导弹 某国为了防御敌国的导弹袭击&#xff0c;发展出一种导弹拦截系统。 但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。 某天&#xff0c;雷达捕捉到敌国的导弹来袭。 由…

最全的3D动画软件介绍来了!良心总结9款3D动画制作必备软件

现在&#xff0c;市面上流行着的3D动画软件如此之多&#xff0c;以至于很难敲定到底哪一款更适合自己或自己的团队。本篇文章带来了一些热门的、被视为行业标准的3D动画软件的介绍&#xff0c;帮助您更好地做出选择。 不仅如此&#xff0c;您还能从文章中了解到在数字内容创建…