React@16.x(23)useEffect

1,介绍

作用

用于在函数组件内,处理副作用,比如:

  • ajax 请求
  • 计时器
  • 其他异步操作
  • 更改真实DOM对象
  • 本地存储
  • 其他会对外部产生影响的操作(和自身无关)。

介绍

useEffect 接收2个参数,

  • 参数1,一个函数。在该函数中执行副作用。
  • 参数2(可选),一个数组。记录参数1中使用到的依赖。
import React, { useEffect, useState } from "react";

export default function App() {
    const [n, setN] = useState(0);
    useEffect(() => {
        document.title = `数字:${n}`;
    });
    return (
        <div>
            <span>{n}</span>
            <button
                onClick={() => {
                    setN(n + 1);
                }}
            >
                加一
            </button>
        </div>
    );
}

2,注意点

2.1,参数1,副作用函数

2.1.1,运行时间点

在页面完成真实UI渲染后执行,并且是异步的,不会阻塞浏览器。

和类组件中的生命周期函数 componentDidMountcomponentDidUpdate区别

它们是同步执行的;在得到真实DOM后,用户还没有看到真实UI渲染时执行。

2.1.2,返回值

要么没有返回值,如果有必须是一个函数。该函数称为清理函数

type EffectCallback = () => void | (() => void);;

清理函数的特点:

  • 首次渲染不会执行,组件销毁一定执行;
  • 再次渲染时,会在副作用函数之前运行。

所以,一般会在清理函数中,清理副作用函数开启的计时器。

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

function Child() {
    useEffect(() => {
        let timer = null;
        let n = 10;
        timer = setInterval(() => {
            console.log(n--);
        }, 1000);
        return () => {
            clearInterval(timer);
        };
    });
    return <div>子组件</div>;
}

export default function App() {
    const [visible, setVisible] = useState(true);
    return (
        <div>
            {visible && <Child />}
            <button
                onClick={() => {
                    setVisible(!visible);
                }}
            >
                显示/隐藏
            </button>
        </div>
    );
}

2.1.3,闭包的影响

在副作用函数中,如果使用了函数组件上下文中的变量,受闭包影响,会导致副作用函数中的变量不会实时变化

原理和闭包的经典问题一样,不同点是这里的 n 是一个状态

也就是说,每次函数组件重新调用,计时器的回调函数使用的都是当次函数组件调用时产生的新值( 相当于计时器中使用了传递的参数)。

所以每次开启新计时器时,n 都不一样。

export default function App() {
    const [n, setN] = useState(10);
    useEffect(() => {
        setTimeout(() => {
            console.log(n);
        }, 3000);
    });
    return (
        <div>
            <button
                onClick={() => {
                    setN(n - 1);
                }}
            >
                n-1
            </button>
        </div>
    );
}

3s 后打印,所以在3s内连续点击按钮3次,3s后会先打印出 10(首次渲染),再依次打印出 9 8 7

2.1.4,严禁出现在代码块中(判断,循环)

原理和 useState 类似,这样写会导致无法正确获取要执行的副作用函数。

2.1.5,尽量保持副作用函数稳定

副作用函数在每次(重新渲染)注册时,会覆盖掉之前的副作用函数,因此,尽量保持副作用函数稳定,否则控制起来会比较复杂。

2.2,参数2,数组

作用:记录副作用函数的依赖数据。当组件重新渲染后,如果新旧依赖数据不一致(Object.is() 判断),才会执行副作用函数。

类似于 Vue3 中的 watcheffect

所以,如果依赖数据没有发生变化,则:

  • 副作用函数仅在组件第一次渲染后执行;
  • 清理函数仅在组件卸载时执行。

参数2传递空数组就能实现依赖不发生变化。

useEffect(() => {
    console.log('副作用函数执行');
    return () => {
        console.log('清理函数执行');
    }
}, [])

比如请求列表数据,当前页码 page 和每页展示个数 limit 发生变化时,再请求接口:

useEffect(() => {
    (async function () {
        const resp = await getList(page, limit);
        // 获取 list 和 total
    })();
}, [page, limit])

以上。

相关推荐

  1. React@16.x23useEffect

    2024-06-09 22:48:03       15 阅读
  2. React@16.x26)useContext

    2024-06-09 22:48:03       11 阅读
  3. React@16.x27)useCallBack

    2024-06-09 22:48:03       9 阅读
  4. React@16.x28)useMemo

    2024-06-09 22:48:03       8 阅读
  5. React@16.x25)useReducer

    2024-06-09 22:48:03       12 阅读
  6. 13 React useEffect 详解

    2024-06-09 22:48:03       16 阅读
  7. React@16.x24)自定义HOOK

    2024-06-09 22:48:03       13 阅读
  8. # 15 React 使用useEffect获取网络数据

    2024-06-09 22:48:03       23 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-09 22:48:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-09 22:48:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-09 22:48:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-09 22:48:03       20 阅读

热门阅读

  1. Python进阶之-mmap详解

    2024-06-09 22:48:03       12 阅读
  2. AcWing 33:链表中倒数第k个节点 ← 尾插法

    2024-06-09 22:48:03       14 阅读
  3. Day06 - Day10

    2024-06-09 22:48:03       12 阅读
  4. es6+-箭头函数细节与应用场景

    2024-06-09 22:48:03       10 阅读
  5. html常见的表单元素有哪些,html表单元素有哪些?

    2024-06-09 22:48:03       10 阅读
  6. adb dump当前可见的窗口

    2024-06-09 22:48:03       10 阅读
  7. View->View测量布局中requestLayout和forceLayout的区别

    2024-06-09 22:48:03       8 阅读
  8. 深入解析JVM内部结构及GC机制的实战应用

    2024-06-09 22:48:03       12 阅读
  9. Linux网络安全

    2024-06-09 22:48:03       10 阅读
  10. 面向对象程序设计

    2024-06-09 22:48:03       13 阅读