React - useEffect函数的理解和使用

news/2024/7/15 18:28:12 标签: react.js, 前端, 前端框架

文章目录

    • 一,useEffect描述
    • 二,它的执行时机
    • 三,useEffect分情况使用
      • 1,不写第二个参数 说明监测所有state,其中一个变化就会触发此函数
      • 2,第二个参数如果是`[]`空数组,说明谁也不监测
      • 3,第二个参数如果只传需要监测的state,那只会根据此状态来执行函数
      • 4,useEffect 里面return一个回调函数,相当于组件即将卸载的声明周期
      • 5,注意

一,useEffect描述

我们知道,react 的函数组件里面没有生命周期的,也没有 state,没有 state 可以用 useState 来替代,那么生命周期呢?

useEffectreact v16.8 新引入的特性。我们可以把 useEffect hook 看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三个生命周期的组合。可以让你在函数式组件中执行一些副作用操作;

一般副作用操作有:

  1. 发送ajax请求
  2. 设置订阅 / 启动定时器
  3. 手动更改真实DOM

二,它的执行时机

可以看做这三个生命周期函数的组合,也就是在这三个时候会执行

componentDidMount(组件已经挂载)

componentDidUpdate(组件已经更新)

componentWillUnmount(组件即将卸载)

三,useEffect分情况使用

useEffect()有两个参数:第一个参数是要执行的回调函数,第二个参数是一个依赖项数组数组(根据需求第二个参数可选是否填写),根据数组里的变量是否变化决定是否执行函数;

先看下面简单的案例 ,下面会分情况讨论:

useEffect.js

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

// 类型约定
interface interList {
  id: number | string; // 类型可能是number也可能是string
  text: string;
  done: boolean;
}
// 渲染数据
const myList: Array<interList> = [
  { id: 0, text: "参观卡夫卡博物馆", done: true },
  { id: 1, text: "看木偶戏", done: true },
  { id: 2, text: "打卡列侬墙", done: true }
];

const UseEffect: React.FC = (props: any) => {
  let [num, setNum] = useState(100);
  let [useInfo, SetUserInfo] = useState(myList);

   // 0,什么都不传 就是监听所有数据的变化
   useEffect(() => {
    console.log("我改变了-all");
  }); 

  // 1,此处相当于 componentDidUpdate生命周期 组件已经更新完成
  useEffect(() => {
    console.log("我改变了");
  }, [num]); // 只监听num的变化,useInfo的变化不会被监听到

  // 2,此处相当于componentDidMount生命周期 组件已经挂载完成
  useEffect(() => {
    console.log("componentDidMount");
    console.log("可以拿到num的值:", num);
  }, []);

  // 3,此处相当于 componentWillUnmount生命周期 组件即将卸载
  useEffect(() => {
    // 返回一个回调函数
    return () => {
      console.log("组件将要卸载了");
    };
  }, []);

  // 其实传不传空数组或不是空数组,useEffect函数里面的回调都会执行一次,也就是说componentWillUnmount这个生命周期页面进来就会执行
  // useEffect 这个hoosk也是可以写多个的,尽量不同的处理写在不同useEffect里面

  // 点击改变用户信息
  const change = () => {
    // react 建议不要更改原数组 返回一个数组的拷贝
    const newList = [...useInfo, { id: 3, text: "优菈", done: false }];
    SetUserInfo(newList);
  };

  // 点击加一
  const add = () => {
    setNum(++num);
  };

  const lis = useInfo.map((item, index) => {
    return (
      <li key={index}>
        {index}:{item.text}
      </li>
    );
  });

  return (
    <>
      <div>
        <h3>userEffect 副作用hooks函数</h3>
        <br />
        <button onClick={add}>点击加一</button>
        <p>{num}</p>
        <br />
        <button onClick={change}>改变用户信息</button>
        <ul>{lis}</ul>
      </div>
    </>
  );
};
export default UseEffect;

效果图:
在这里插入图片描述

上面代码实现的效果很简单,两个按钮分别改变各自数据的状态,状态的改变会触发 useEffect函数的执行,第二个参数的传参影响着此函数的变化,所以下面进行分情况讨论:

1,不写第二个参数 说明监测所有state,其中一个变化就会触发此函数

若不写第二个参数,函数操作每次都会执行 useEffect(method)监测所有state,相当于 componentDidUpdate生命周期 - 组件已经更新完成。

   import {useEffect } from "react";
   useEffect(() => {
    console.log("我改变了-all");
  }); // 监听所有数据的变化

2,第二个参数如果是[]空数组,说明谁也不监测

第二个参数如果是[]空数组,说明谁也不监测,此时useEffect回调函数的作用就相当于
componentDidMount生命周期 - 组件已经挂载完成;

  // 2,此处相当于componentDidMount生命周期 组件已经挂载完成
  useEffect(() => {
    console.log("componentDidMount");
    console.log("可以拿到num的值:", num);
  }, []);

3,第二个参数如果只传需要监测的state,那只会根据此状态来执行函数

如果第二个参数中的数组只传了 num ,说明只有 num改变时,才会触发此useEffect回调函数,相当于对此数据的监听。

  // 1,此处相当于 componentDidUpdate生命周期 组件已经更新完成
  useEffect(() => {
    console.log("num改变了");
  }, [num]); // 只监听num的变化

当然数组里面也可以写多个([num,userInfo]),同时监听多个数据的变化。

4,useEffect 里面return一个回调函数,相当于组件即将卸载的声明周期

这句话什么意思呢?
通常,组件是有卸载的生命周期的,使用useEffect 函数只需在里面return一个回调函数,这个回调函数就相当于componentWillUnmount 声明周期,可以在里面清除创建的订阅或计时器 ID 等资源。

  // 3,此处相当于 componentWillUnmount生命周期 组件即将卸载
  useEffect(() => {
    // 返回一个回调函数
    return () => {
      console.log("组件将要卸载了");
    };
  }, []);

这里传了空数组说明我不想监听数据的变化,只想在卸载组件的时候执行该逻辑;

5,注意

其实第二个传不传空数组或不是空数组,useEffect函数里面的回调都会执行一次,也就是说页面进来就会自动执行componentWillUnmount这个生命周期;

useEffect函数 这个hoosk也是可以写多个的,尽量不同的业务处理写在不同useEffect里面;


http://www.niftyadmin.cn/n/4931685.html

相关文章

matplotlib 为图顶部和图右部的坐标轴添加标记label

Matplotlib 中&#xff0c;默认情况下&#xff0c;只有底部和左侧的坐标轴有标记 1 设置底部坐标轴标签 通过使用ax.xaxis.set_label_position() 调整标签的位置 import matplotlib.pyplot as plt# 创建一个图表 fig, ax plt.subplots()# 生成示例数据 x [1, 2, 3, 4, 5] …

echarts barEchart柱状图边框、透明、文字靠左展示

效果一 先上效果图 说明&#xff1a; 给柱状图加上 边框&#xff0c;改变柱状图颜色并透明&#xff0c;改变 X,Y轴字体颜色&#xff0c;改变 轴线颜色&#xff0c;将所有的轴线全都改成一致效果 echarts 的代码 javascript const renderBarEcharts (ele: HTMLDivElement) >…

ApacheCon - 云原生大数据上的 Apache 项目实践

Apache 软件基金会的官方全球系列大会 CommunityOverCode Asia&#xff08;原 ApacheCon Asia&#xff09;首次中国线下峰会将于 2023 年 8 月 18-20 日在北京丽亭华苑酒店举办&#xff0c;大会含 17 个论坛方向、上百个前沿议题。 字节跳动云原生计算团队在此次 CommunityOve…

【SpringBoot】88、SpringBoot中使用Undertow替代Tomcat容器

SpringBoot 中我们既可以使用 Tomcat 作为 Http 服务,也可以用 Undertow 来代替。Undertow 在高并发业务场景中,性能优于 Tomcat。所以,如果我们的系统是高并发请求,不妨使用一下 Undertow,你会发现你的系统性能会得到很大的提升。 1、Tomcat 介绍 Tomcat是一个开源的Ja…

网站SSL安全证书是什么及其重要性

网站SSL安全证书具体来说是一个数字文件&#xff0c;是由受信任的数字证书颁发机构&#xff08;CA机构&#xff09;进行审核颁发的&#xff0c;其中包含CA发布的信息&#xff0c;该信息表明该网站已使用加密连接进行了安全保护。 网站SSL安全证书也被称为SSL证书、https证书和…

android ndk clang交叉编译ffmpeg动态库踩坑

1.ffmpeg默认使用gcc编译&#xff0c;在android上无法使用&#xff0c;否则各种报错&#xff0c;所以要用ndk的clang编译 2.下载ffmpeg源码 修改configure文件&#xff0c;增加命令 cross_prefix_clang 修改以下命令 cc_default"${cross_prefix}${cc_default}" cxx…

web-vue

<html><head><title>永远朋友</title><script src"../js/vue.js"></script></head><body><div id "app"><input type"text" v-model"message">{{ message }}</div&g…

正则表达式试炼

我希望在这里列出我很多想写的正则表达式&#xff0c;很多我想写&#xff0c;但是不知道怎么写的。分享点滴案例。未来这个文章会越来越长 案例 我有这样的一批文字&#xff0c;我需要删掉Mozilla/5.0前面的所有内容&#xff0c;如果可以用正则表达式批量匹配到&#xff0c;删…