react 中 useEffect Hook 作用

news/2024/11/20 11:08:09/

`useEffect`是一个用于处理副作用(Side Effects)的 Hook

一、处理副作用

1. 副作用的概念

副作用是指在组件渲染过程中执行的、会影响组件外部环境或具有外部可见影响的操作。

常见的副作用包括数据获取(如从服务器获取数据)、订阅外部数据源(如消息队列、事件总线)、手动操作 DOM(如修改页面标题、滚动位置)以及设置定时器等。

2. useEffect 基本用法

2.1 语法结构

`useEffect`接受两个参数,第一个参数是一个函数,称为副作用函数(Effect Function),在这个函数内部执行实际的副作用操作。第二个参数是一个可选的依赖项数组(Dependency Array)。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {// 这是一个副作用函数,这里模拟从服务器获取数据console.log("Fetching data...");return () => {// 可选的清理函数,用于在组件卸载或依赖项变化时清理副作用console.log("Cleaning up...");};}, []);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);};export default MyComponent;

在这个例子中,副作用函数在组件挂载时执行,因为依赖项数组为空(`[]`),表示这个副作用只在组件初始化时触发一次。副作用函数还返回了一个清理函数,用于在组件卸载或依赖项变化时执行清理操作。

二、模拟生命周期方法

1. 替代 componentDidMount

在类组件中,`componentDidMount`方法在组件挂载到 DOM 后立即执行。在函数组件中,可以使用`useEffect`来实现类似的功能。当`useEffect`的依赖项数组为空时,副作用函数在组件第一次渲染(挂载)后执行,相当于`componentDidMount`。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [data, setData] = useState(null);useEffect(() => {// 模拟在组件挂载后获取数据,相当于componentDidMountfetch("https://example.com/api/data").then((response) => response.json()).then((jsonData) => setData(jsonData));}, []);return <div>{data ? <p>{data}</p> : <p>Loading...</p>}</div>;};export default MyComponent;

2. 替代 componentDidUpdate

在类组件中,`componentDidUpdate`方法在组件每次更新(`state`或`props`变化)后执行。在函数组件中,可以通过在`useEffect`的依赖项数组中指定依赖项来模拟`componentDidUpdate`。当依赖项发生变化时,副作用函数会重新执行,类似于`componentDidUpdate`。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);const [data, setData] = useState(null);useEffect(() => {// 当count变化时,重新获取数据,类似于componentDidUpdateif (count > 0) {fetch("https://example.com/api/data").then((response) => response.json()).then((jsonData) => setData(jsonData));}}, [count]);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button>{data ? <p>{data}</p> : <p>Loading...</p>}</div>);};export default MyComponent;

3. 替代 componentWillUnmount

在类组件中,`componentWillUnmount`方法在组件卸载前执行,用于清理资源。在函数组件中,`useEffect`的副作用函数返回的清理函数在组件卸载或依赖项变化时执行,从而替代了`componentWillUnmount`的功能。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {const timer = setInterval(() => {setCount(count + 1);}, 1000);return () => {// 组件卸载或依赖项变化时清除定时器,相当于componentWillUnmountclearInterval(timer);};}, []);return (<div><p>Count: {count}</p></div>);};export default MyComponent;

三、依赖项管理和优化

1. 依赖项的作用

1.1 决定副作用执行时机

例如:如果一个副作用函数依赖于组件的某个状态值,将这个状态值放入依赖项数组中,那么当这个状态值改变时,副作用函数就会重新运行。这样可以确保副作用与组件的状态和属性保持同步。

2. 优化性能

例如:在不必要的时候重复获取数据或重新订阅事件,浪费资源并可能导致应用程序性能下降。

3. 优化策略和常见错误

3.1 空依赖项数组的优化与风险

例如:初始化数据获取或设置全局事件监听器。但如果在副作用函数中使用了组件的状态或属性,并且没有将它们包含在依赖项数组中,就会导致闭包问题。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {// 错误:没有将count包含在依赖项数组中,导致闭包问题console.log("Count:", count);}, []);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);};export default MyComponent;

3.2 正确指定依赖项

为了避免上述问题,需要将副作用函数中使用的所有组件的状态、属性以及其他外部函数(如果在副作用函数内部调用)都包含在依赖项数组中。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {console.log("Count:", count);}, [count]);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);};export default MyComponent;


http://www.ppmy.cn/news/1548473.html

相关文章

### 哋它亢在5G基站中的应用:新兴技术与未来通信的融合

文章目录 1. 什么是“哋它亢”&#xff1f;2. 哋它亢的原理与优势3. 哋它亢在5G基站中的应用场景4. 哋它亢技术的挑战与未来展望 随着通信技术的不断发展&#xff0c;我们迎来了5G时代&#xff0c;这为我们的日常生活带来了诸多变化。5G不仅提升了网络速度&#xff0c;还为各种…

枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~

目录 认识枚举 全文重点&#xff1a;枚举在单例模式中为什么是安全的&#xff1f; Lambda 表达式 概念&#xff1a; 函数式接口 lambda表达式的基本使用&#xff1a; lambda表达式的语法精简&#xff1a; lambda表达式的变量捕获 Lambda在集合当中的使用 在 Collecti…

论文翻译 | Learning to Transfer Prompts for Text Generation

摘要 预训练语言模型&#xff08;PLMs&#xff09;通过微调在文本生成任务中取得了显著进展。然而&#xff0c;在数据稀缺的情况下对plm进行微调是具有挑战性的。因此&#xff0c;开发一个通用的、轻量级的、能够适应各种基于plm的文本生成任务的模型是非常重要的。为了实现这一…

QT基础 窗体 对话框 文件 QT5.12.3环境 C++实现

一、堆栈窗体 1. 概念 是一种界面设计思路&#xff0c; 多个窗体重叠在一起&#xff0c;通过点击对应的按钮&#xff0c;显示对应的界面。 2. 相关方法 Public FunctionsQStackedWidget(QWidget * parent 0)//stack如果单纯指定父窗口&#xff0c;但是没有指定大小&#xf…

硬件知识 cadence16.6 原理图输出为pdf 网络名下划线偏移 (ORCAD)

1. cadence原理图输出为PDF网络名下划线偏移 生这种情况的原因 1. 设计的原理图图纸大小比正常的 A4图纸大。 2. 打印为PDF 的时候&#xff0c;打印机的设置有问题。 2.cadence原理图输出为 PDF网络名下划线偏移的情况 可以看到上图&#xff0c;网络名往上漂移。 3. 解决办法 …

【WPF】Prism学习(二)

Prism Commands 1.命令&#xff08;Commanding&#xff09; 1.1. ViewModel的作用&#xff1a; ViewModel不仅提供在视图中显示或编辑的数据&#xff0c;还可能定义一个或多个用户可以执行的动作或操作。这些用户可以通过用户界面&#xff08;UI&#xff09;执行的动作或操作…

Linux Docker 部署 Jenkins 详解教程

一、环境准备 安装 Docker 在开始之前&#xff0c;确保你的 Linux 系统已经安装了 Docker。以下是 CentOS 系统的安装步骤&#xff1a; # 确保 yum 包更新到最新 yum update -y# 卸载旧版本(如果安装过旧版本的话) yum remove docker docker-common docker-selinux docker-engi…

Matlab 二维矩形板模态和固有频率的Matlab有限元法实现

本文给出了尺寸为200mm x 500mm x 2mm的二维矩形板的前六个固有频率和模态振型的评估结果&#xff0c;假设是一扇门&#xff0c;在某些点上有运动限制&#xff0c;假设是门环和把手。在MATLAB中通过自学算法进行评估&#xff0c;并将结果与COMSOL模拟进行比较。网格&#xff0c…