React - useEffect函数的理解和使用

文章目录

一,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

javascript 复制代码
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生命周期 - 组件已经更新完成。

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

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

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

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

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

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

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

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

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

这句话什么意思呢?

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

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

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

5,注意

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

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

相关推荐
蟾宫曲2 小时前
在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)
前端·npm·vue3·vite·element-plus·计时器
秋雨凉人心2 小时前
简单发布一个npm包
前端·javascript·webpack·npm·node.js
liuxin334455662 小时前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
qq13267029402 小时前
运行Zr.Admin项目(前端)
前端·vue2·zradmin前端·zradmin vue·运行zradmin·vue2版本zradmin
魏时烟3 小时前
css文字折行以及双端对齐实现方式
前端·css
2401_882726484 小时前
低代码配置式组态软件-BY组态
前端·物联网·低代码·前端框架·编辑器·web
web130933203984 小时前
ctfshow-web入门-文件包含(web82-web86)条件竞争实现session会话文件包含
前端·github
胡西风_foxww4 小时前
【ES6复习笔记】迭代器(10)
前端·笔记·迭代器·es6·iterator
前端没钱5 小时前
探索 ES6 基础:开启 JavaScript 新篇章
前端·javascript·es6
m0_748255265 小时前
vue3导入excel并解析excel数据渲染到表格中,纯前端实现。
前端·excel