当前位置: 首页 > article >正文

第八部分:第五节 - 生命周期与副作用 (`useEffect` Hook):组件的幕后工作

知识点: 组件生命周期(挂载 Mounting, 更新 Updating, 卸载 Unmounting - 高级概念),副作用 (Side Effects),useEffect Hook (用于处理副作用,如数据获取、订阅、DOM 操作),useEffect 的依赖数组,useEffect 的清理函数。

讲解:

React 组件有自己的“生命周期”,从被创建并添加到页面上(挂载),到数据或状态变化导致重新渲染(更新),再到从页面上移除(卸载)。在这些生命周期的不同阶段,我们可能需要执行一些“副作用”操作。

副作用 (Side Effects):

副作用是指在组件渲染过程中不是直接计算结果的操作。常见的副作用包括:

  • 数据获取 (Data Fetching): 从后端 API 请求数据。
  • 订阅 (Subscriptions): 建立 WebSocket 连接,监听事件等。
  • 手动修改 DOM: 直接操作浏览器 DOM (通常不推荐,除非必要)。
  • 定时器 (Timers): 设置 setTimeout 或 setInterval。
  • 日志记录 (Logging)。

这些操作不能直接放在组件函数体中(会无限循环或只执行一次),需要特殊的机制来管理。

useEffect Hook:

在功能组件中,我们使用 useEffect Hook 来处理副作用。useEffect 可以在组件渲染后执行代码。你可以把它想象成告诉 React:“在 DOM 更新后,帮我运行这段代码。”

useEffect 接收一个函数作为第一个参数,这个函数就包含了你要执行的副作用代码。

import React, { useState, useEffect } from 'react';function DataFetcher() {const [data, setData] = useState(null);const [isLoading, setIsLoading] = useState(true);// 使用 useEffect 处理数据获取副作用useEffect(() => {console.log('useEffect 运行了');// 在这里执行异步数据获取fetch('https://api.example.com/data') // 假设这是一个获取数据的 API.then(response => response.json()).then(data => {setData(data);setIsLoading(false);}).catch(error => {console.error('数据获取出错:', error);setIsLoading(false);});// useEffect 的默认行为是在每次渲染后都运行副作用函数// 这通常不是我们想要的,需要使用依赖数组控制执行时机}); // 没有依赖数组,每次渲染后都运行if (isLoading) {return <p>正在加载数据...</p>;}if (!data) {return <p>加载数据失败。</p>;}return (<div><h2>获取到的数据</h2><pre>{JSON.stringify(data, null, 2)}</pre></div>);
}

useEffect 的依赖数组 (Dependency Array):

useEffect 的第二个参数是一个依赖数组。它告诉 React 副作用应该在何时重新运行。

  • 没有依赖数组: 副作用在每次渲染后都运行。
  • 空数组 []: 副作用只在组件第一次挂载时运行一次 (componentDidMount 的替代)。适合执行一次性的设置或数据获取。
  • 包含变量的数组 [variable1, variable2]: 副作用在组件第一次挂载时运行一次,并且在依赖数组中的任何变量发生变化时重新运行。适合根据某些 State 或 Props 的变化来执行副作用。
// 只在组件挂载时获取一次数据 (空数组 [])
useEffect(() => {console.log('组件挂载,只运行一次');// 获取数据的代码...
}, []); // 空依赖数组// 当 userId 变化时重新获取数据
useEffect(() => {console.log('userId 或组件挂载时运行');if (userId) {// 根据新的 userId 获取用户详情fetch(`https://api.example.com/users/${userId}`).then(response => response.json()).then(userData => {// ... 更新用户 State});}
}, [userId]); // 依赖数组包含 userId// 没有依赖数组 (不推荐用于数据获取等异步操作,可能导致无限循环)
// useEffect(() => {
//   console.log('每次渲染后都运行');
// });

useEffect 的清理函数 (Cleanup Function):

有时候,副作用需要在组件卸载时下次副作用重新运行前进行清理,以避免内存泄漏或不必要的行为。比如清除定时器、取消订阅、关闭网络连接等。useEffect 可以选择返回一个函数,这个函数就是清理函数。

useEffect(() => {console.log('副作用设置');// 设置一个定时器const timerId = setInterval(() => {console.log('定时器运行中...');}, 1000);// 返回一个清理函数return () => {console.log('副作用清理');// 清除定时器clearInterval(timerId);};
}, []); // 空依赖数组,只在挂载时设置定时器,在卸载时清除

清理函数会在组件卸载时执行。如果 useEffect 因为依赖项变化而重新运行,清理函数会在新的副作用运行之前执行。

小结: useEffect Hook 是功能组件中处理副作用的核心工具。通过依赖数组可以控制副作用的执行时机(挂载时、更新时、特定依赖变化时)。返回清理函数可以处理副作用的清理工作,避免资源泄漏。理解 useEffect 是掌握在 React 中进行异步操作和与外部系统交互的关键。

练习:

  1. 在你的 my-restaurant-app 项目中,修改 MenuList 组件。
  2. 使用 useState 创建一个 State 变量 menuItemsisLoading (初始为 true)。
  3. 使用 useEffect Hook,在组件挂载时(空依赖数组),模拟从后端 API 获取菜单数据。你可以使用 setTimeout 延迟几秒来模拟网络请求。
  4. 在模拟请求成功后,更新 menuItems State,并将 isLoading 设置为 false。
  5. 在组件的 JSX 中,使用条件渲染:如果 isLoading 为 true,显示“菜单加载中…”,否则渲染菜单列表 (menuItems.map(...))。
  6. (进阶)创建一个新的组件 Timer.jsx。使用 useStateuseEffect 来创建一个简单的计时器,每秒更新并显示当前时间。在 useEffect 中设置 setInterval,并返回一个清理函数来清除定时器。

相关文章:

第八部分:第五节 - 生命周期与副作用 (`useEffect` Hook):组件的幕后工作

知识点&#xff1a; 组件生命周期&#xff08;挂载 Mounting, 更新 Updating, 卸载 Unmounting - 高级概念&#xff09;&#xff0c;副作用 (Side Effects)&#xff0c;useEffect Hook (用于处理副作用&#xff0c;如数据获取、订阅、DOM 操作)&#xff0c;useEffect 的依赖数组…...

docker 搭建php 开发环境 添加扩展redis、swoole、xdebug(2)

3、创建compose 的yml文件 version: "3.9" services:#配置nginxnginx:#镜像名称 nginx:latestimage: nginx#自定义容器的名称#container_name: c_nginxports:- "80:80"#lnmp目录和容器的/usr/share/nginx/html目录进行绑定,设置rw权限#将宿主机的~/lnmp/…...

DeepSwiftSeek 开源软件 |用于 DeepSeek LLM 模型的 Swift 客户端 |轻量级和高效的 DeepSeek 核心功能通信

​一、软件介绍 文末提供程序和源码下载 DeepSeek Swift SDK 是一个轻量级且高效的基于 Swift 的客户端&#xff0c;用于与 DeepSeek API 进行交互。它支持聊天消息完成、流式处理、错误处理以及使用高级参数配置 DeepSeekLLM。 二、Features 特征 Supports chat completion …...

Flask-Login使用示例

项目结构 首先创建以下文件结构&#xff1a; flask_login_use/ ├── app.py ├── models.py ├── requirements.txt └── templates/├── base.html├── index.html├── login.html├── register.html└── profile.html1. requirements.txt Flask2.3.3 Fl…...

React Hooks 基础指南

React Hooks 是 React 16.8 引入的重要特性&#xff0c;它允许开发者在函数组件中使用状态和其他 React 特性。本文将详细介绍 6 个最常用的 React Hooks。 1. useState useState 是最常用的 Hook&#xff0c;用于在函数组件中添加 state。 import React, { useState } from…...

web第九次课后作业--SpringBoot基于mybatis实现对数据库的操作

前言 在前面我们学习MySQL数据库时&#xff0c;都是利用图形化客户端工具(如&#xff1a;idea、datagrip)&#xff0c;来操作数据库的。 在客户端工具中&#xff0c;编写增删改查的SQL语句&#xff0c;发给MySQL数据库管理系统&#xff0c;由数据库管理系统执行SQL语句并返回执…...

沪铜6月想法

市场回顾 2025年5月&#xff0c;沪铜期货主力合约价格整体呈现震荡走势。从月初到月末&#xff0c;价格在7.67-7.82万元/吨之间波动。截至5月31日&#xff0c;沪铜主力合约收盘价为7.76万元/吨。本月铜价围绕供需基本面和宏观政策预期展开波动&#xff0c;尤其在5月14日至5月1…...

网络通信核心概念全解析:从IP地址到TCP/UDP实战

一、网络基础架构三要素 1. IP地址&#xff1a;互联网的“门牌号” 本质&#xff1a;32位整数标识主机位置&#xff08;IPv4&#xff09;表示法&#xff1a;点分十进制&#xff08;如 192.168.1.1&#xff09;功能&#xff1a;全球唯一标识网络设备特殊地址&#xff1a; 127.…...

Spring 中的disposableBean介绍

在 Spring 框架中&#xff0c;DisposableBean 是一个接口&#xff0c;用于定义 Bean 在被销毁前需要执行的清理逻辑。它是 Spring 容器生命周期回调机制的一部分。 &#x1f331; 什么是 DisposableBean DisposableBean 接口是 Spring 提供的一个标准接口&#xff0c;用于通知…...

【Linux命令学习】获取cpu信息 - lscpu命令学习

lscpu命令显示的是服务器cpu架构相关信息&#xff0c;lscpu从伪文件系统(sysfs)、/proc/cpuinfo和任何可用的特定体系架构库中收集cpu架构信息。输出内容包括&#xff1a;CPU、线程、内核的数量以及非同一存储器存取节点。此外还包括关于CPU高速缓存和高速缓存共享的信息&#…...

wordpress免费主题网站

这是一款WordPress主题&#xff0c;由jianzhanpress开发&#xff0c;可以免费下载。专为中小微企业设计&#xff0c;提供专业的网站建设、网站运营维护、网站托管和网站优化等服务。主题设计简约、现代&#xff0c;适合多种行业需求。 主要特点&#xff1a; 多样化展示&#…...

Go中的协程并发和并发panic处理

1 协程基础 1.1 协程定义&#xff08;Goroutine&#xff09; 概念&#xff1a;Go 语言特有的轻量级线程&#xff0c;由 Go 运行时&#xff08;runtime&#xff09;管理&#xff0c;相比系统线程&#xff08;Thread&#xff09;&#xff0c;创建和销毁成本极低&#xff0c;占用…...

Qt Creator工具编译器配置

1、打开Qt Creator&#xff0c;工具-->选项 2、选择"编译器"&#xff0c;Manual配置编译器。 初始化填入“C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe”&#xff0c;选择64位amd64。 ABI根据msvc版本进行选择msvc2015. 3、新建项目…...

从零开始的数据结构教程(六) 贪心算法

&#x1f36c; 标题一&#xff1a;贪心核心思想——发糖果时的最优分配策略 贪心算法 (Greedy Algorithm) 是一种简单直观的算法策略。它在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望得到一个全局最优解。这就像你…...

Spring框架学习day7--SpringWeb学习(概念与搭建配置)

SpringWeb1.SpringWeb特点2.SpringWeb运行流程3.SpringWeb组件4.搭建项目结构图&#xff1a;4.1导入jar包4.2在Web.xml配置**4.2.1配置统一拦截分发器 DispatcherServlet**4.2.2开启SpringWeb注解&#xff08;spring.xml&#xff09; 5.处理类的搭建6.SpringWeb请求流程(自己理…...

打造高效多模态RAG系统:原理与评测方法详解

引言 随着信息检索与生成式AI的深度融合&#xff0c;检索增强生成&#xff08;RAG, Retrieval-Augmented Generation&#xff09; 已成为AI领域的重要技术方向。传统RAG系统主要依赖文本数据&#xff0c;但真实世界中的信息往往包含图像、表格等多模态内容。多模态RAG&#xf…...

SSM 框架核心知识详解(Spring + SpringMVC + MyBatis)

&#x1f331; 第一部分&#xff1a;Spring 核心原理与使用 1. 什么是 Spring Spring 是一个开源的 Java 企业级开发框架&#xff0c;旨在简化 Java 企业应用程序开发。它核心思想是控制反转&#xff08;IoC&#xff09;和面向切面编程&#xff08;AOP&#xff09;&#xff0…...

1.2 fetch详解

浏览器 Fetch API 详解 Fetch API 是现代浏览器提供的用于发起网络请求的接口&#xff0c;它基于 Promise 实现&#xff0c;替代了传统的 XMLHttpRequest&#xff0c;提供了更强大、更灵活的功能。 1. 基本用法 使用 fetch() 函数发起请求&#xff0c;返回一个 Promise&…...

【C#】Quartz.NET怎么动态调用方法,并且根据指定时间周期执行,动态配置类何方法以及Cron表达式,有请DeepSeek

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01;&#…...

02 Deep learning神经网络的编程基础 逻辑回归--吴恩达

逻辑回归 逻辑回归是一种用于解决二分类任务&#xff08;如预测是否是猫咪等&#xff09;的统计学习方法。尽管名称中包含“回归”&#xff0c;但其本质是通过线性回归的变体输出概率值&#xff0c;并使用Sigmoid函数将线性结果映射到[0,1]区间。 以猫咪预测为例 假设单个样…...

Android Native 内存泄漏检测全解析:从原理到工具的深度实践

引言 Android应用的内存泄漏不仅发生在Java/Kotlin层&#xff0c;Native&#xff08;C/C&#xff09;层的泄漏同样普遍且隐蔽。由于Native内存不受Java虚拟机&#xff08;JVM&#xff09;管理&#xff0c;泄漏的内存无法通过GC自动回收&#xff0c;长期积累会导致应用内存占用…...

React---扩展补充

一些额外的扩展 4.3 高阶组件 高阶组件是参数为组件&#xff0c;返回值为新组件的函数&#xff1b; 高阶组件 本身不是一个组件&#xff0c;而是一个函数&#xff1b;其次&#xff0c;这个函数的参数是一个组件&#xff0c;返回值也是一个组件&#xff1b; import React fr…...

HTML 中 class 属性介绍、用法

1、&#x1f516; 什么是 class class 是 HTML 元素的一个核心属性&#xff0c;用来为元素指定一个或多个类名。它在网页开发中承担三大作用&#xff1a; &#x1f3a8; 连接样式&#xff08;CSS&#xff09;&#xff1a;让元素应用预定义的视觉效果⚙️ 绑定行为&#xff08…...

MySQL的并发事务问题及事务隔离级别

一、并发事务问题 1). 赃读&#xff1a;一个事务读到另外一个事务还没有提交的数据。 比如 B 读取到了 A 未提交的数据。 2). 不可重复读&#xff1a;一个事务先后读取同一条记录&#xff0c;但两次读取的数据不同&#xff0c;称之为不可重复读。 事务 A 两次读取同一条记录&…...

ProfiNet 分布式 IO 在某污水处理厂的应用

随着城市化进程的加速&#xff0c;污水处理厂的规模和复杂性不断增加&#xff0c;对自动化控制系统的要求也越来越高。PROfinet 分布式 IO 作为一种先进的工业通信技术&#xff0c;以其高速、可靠、灵活的特性&#xff0c;为污水处理厂的自动化升级提供了有力支持。本文将结合某…...

vue2使用笔记、vue2和vue3的区别

文章目录 vue2和vue3的区别1. 实现数据响应式的原理不同2. 生命周期不同3. vue 2.0 采用了 option 选项式 API&#xff0c;vue 3.0 采用了 composition 组合式 API4. 新特性编译宏5. 父子组件间双向数据绑定 v-model 不同6. v-for 和 v-if 优先级不同7. 使用的 diff 算法不同8.…...

Vue2数组数字字段求和技巧 数字求和方法

<template><div><p>总和: {{ totalSum }}</p></div> </template><script> export default {data() {return {items: [{ id: 1, value: 10 },{ id: 2, value: 20 },{ id: 3, value: 30 }]};},computed: {totalSum() {return this.ite…...

vue2 , el-select 多选树结构,可重名

人家antd都支持&#xff0c;elementplus 也支持&#xff0c;vue2的没有&#xff0c;很烦。 网上其实可以搜到各种的&#xff0c;不过大部分不支持重名&#xff0c;在删除的时候可能会删错&#xff0c;比如树结构1F的1楼啊&#xff0c;2F的1楼啊这种同时勾选的情况。。 可以全…...

Excel处理控件Aspose.Cells教程:使用 C# 从 Excel 进行邮件合并

邮件合并功能让您能够轻松批量创建个性化文档&#xff0c;例如信函、电子邮件、发票或证书。您可以从模板入手&#xff0c;并使用电子表格中的数据进行填充。Excel 文件中的每一行都会生成一个新文档&#xff0c;并在正确的位置包含正确的详细信息。这是一种自动化重复性任务&a…...

Jenkins | Jenkins构建成功服务进程关闭问题

Jenkins构建成功服务进程关闭问题 1. 原因2. 解决 1. 原因 Jenkins 默认会在构建结束时终止所有由构建任务启动的子进程&#xff0c;即使使用了nohup或后台运行符号&。 2. 解决 在启动脚本中加上 BULID_IDdontkillme #--------------解决jenkins 自动关闭进程问题-----…...