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

React的基础API介绍(一)

目录

    • useEffect
      • 1. 替代生命周期方法
      • 2. 副作用管理
      • 3. 依赖项数组
      • 4. 多次使用
      • 5. 与闭包配合
      • 6. 支持异步操作
      • 7. 减少样板代码
    • 注意事项
    • useEffetct是如何拿到变量count最新的值?
      • 1. 每次渲染都会创建新的函数作用域
      • 2. 闭包捕获最新的状态值
      • 3. useEffect 的执行时机
    • useLayoutEffect 与 useEffect
      • 1. useLayoutEffect:
      • 2. useEffect:
    • createRef和useRef
      • 1. createRef
      • 2. useRef
      • 特性对比

useEffect

useEffect 是 React 中的一个 Hook,用于在函数组件中处理副作用操作,例如数据获取、订阅事件、手动修改 DOM 等。以下是 useEffect 的一些主要特性和优点:

1. 替代生命周期方法

模拟类组件的生命周期:useEffect 可以模拟类组件的 componentDidMount、componentDidUpdate 和 componentWillUnmount 方法,允许在组件的不同阶段执行相应的逻辑。

useEffect(() => {// componentDidMount 和 componentDidUpdate 的逻辑return () => {// componentWillUnmount 的逻辑};
}, [dependencies]);

2. 副作用管理

处理副作用:useEffect 在组件渲染后执行,用于处理需要在渲染后发生的副作用,例如更新 DOM、设置订阅、发送网络请求等。

清理副作用:
a. 组件卸载时(Unmount):当组件从界面上被移除时,React 会调用 useEffect 返回的清除函数。这确保了任何与该组件相关的订阅、计时器或其他副作用在组件不再存在时被正确清理。

b. 在重新执行 effect 之前:如果 useEffect 的依赖项数组中的某个值发生了变化,React 会在重新执行 effect 之前调用上一次 effect 的清除函数。这避免了副作用的累积,并确保每次 effect 执行前的环境是干净的。

useEffect(() => {const subscription = someService.subscribe();return () => {subscription.unsubscribe();};
}, []);

3. 依赖项数组

精确控制 effect 执行时机:依赖项数组 [dependencies] 允许你指定 effect 何时重新执行。只有当数组中的依赖项发生变化时,effect 才会被触发。空数组的话只执行一次,相当于componentDidMount

避免不必要的更新:通过正确设置依赖项数组,可以避免不必要的 effect 执行,提高组件性能。

useEffect(() => {// 仅当 count 变化时执行
}, [count]);

4. 多次使用

拆分逻辑:可以在同一个组件中多次使用 useEffect,每个 effect 钩子可以处理不同的副作用逻辑,保持代码清晰。

useEffect(() => {// 处理订阅逻辑
}, []);useEffect(() => {// 处理数据获取逻辑
}, [dataId]);

5. 与闭包配合

访问最新的 state 和 props:useEffect 内部的函数会捕获到当前渲染周期的 state 和 props,确保副作用操作基于最新的数据。

6. 支持异步操作

处理异步任务:useEffect 可以轻松处理异步操作,如数据获取和定时器。

useEffect(() => {async function fetchData() {const result = await axios.get('/api/data');setData(result.data);}fetchData();
}, []);

7. 减少样板代码

简化代码结构:相比于类组件的生命周期方法,useEffect 在函数组件中使用更加简洁,减少了样板代码,使代码更易读。

优点总结

简洁性:使函数组件能够方便地管理副作用,减少了对类组件的依赖。
可读性:通过拆分不同的 useEffect,逻辑更清晰,代码更易于维护。
性能优化:通过依赖项数组,避免了不必要的副作用执行,提高了应用性能。
一致性:提供了统一的方式来处理组件的副作用,减少了认知负担。

注意事项

  1. 正确使用依赖项数组:确保在依赖项数组中包含所有在 effect 中使用的外部变量,防止因为闭包导致的状态不一致问题。
  2. 避免无限循环:如果不慎遗漏依赖项,或者依赖项数组变化过于频繁,可能导致 effect 无限执行,造成性能问题。
  3. 清理函数的重要性:对于订阅、计时器等副作用,一定要在清理函数中进行清理,防止内存泄漏。

示例代码

import React, { useState, useEffect } from 'react';function ChatRoom({ roomId }) {const [messages, setMessages] = useState([]);useEffect(() => {// 订阅聊天信息const subscription = ChatAPI.subscribeToRoom(roomId, (newMessage) => {setMessages((prevMessages) => [...prevMessages, newMessage]);});// 清理函数,取消订阅return () => {ChatAPI.unsubscribeFromRoom(roomId, subscription);};}, [roomId]); // 当 roomId 变化时,重新订阅return (<div>{messages.map((message) => (<p key={message.id}>{message.content}</p>))}</div>);
}

在上述示例中:

使用了 useEffect 来订阅和取消订阅聊天信息。
依赖项数组 [roomId] 确保当房间 ID 变化时,重新执行 effect。
返回的清理函数确保在组件卸载或 roomId 变化时,取消之前的订阅。

useEffetct是如何拿到变量count最新的值?

示例:

function Counter() {  const [count, setCount] = useState(0);    useEffect(() => {   document.title = `You clicked ${count} times`;  });  return (    <div>      <p>You clicked {count} times</p>      <button onClick={() => setCount(count + 1)}>        Click me      </button>   </div>  );
}

useEffect 中的函数能够读取到最新的 count 状态值,主要是由于 JavaScript 中的闭包机制和 React 函数组件的渲染逻辑。

1. 每次渲染都会创建新的函数作用域

新的渲染上下文:在 React 中,每当组件的状态或属性发生变化时,组件都会重新渲染。对于函数组件来说,这意味着组件函数会被重新执行,生成新的渲染结果。
新的变量和函数:每次渲染都会创建新的作用域,其中的变量(如 count)和函数(如传递给 useEffect 的函数)都是新的。

2. 闭包捕获最新的状态值

闭包机制:JavaScript 中,函数会捕获其外部作用域中使用的变量。这意味着在每次渲染时,useEffect 中的函数都会捕获到当次渲染时的 count 值。
最新的 count 值:由于 count 是在组件函数执行时定义的,每次渲染都会得到最新的状态值。useEffect 中的函数在被调用时,使用的就是这个最新的 count 值。

3. useEffect 的执行时机

在渲染后执行:useEffect 中的函数会在组件渲染到屏幕后执行。即使它在渲染期间定义,但执行是在 DOM 更新之后。
每次渲染后执行:在您的示例中,由于没有指定依赖项数组,useEffect 会在每次渲染后执行,因此每次都会使用最新的 count 值。

综合解释

  1. 函数组件的特性:函数组件在每次渲染时都会重新执行函数体,生成新的 count、setCount,以及新的 useEffect 中的函数。
  2. 闭包捕获:useEffect 中的函数在定义时,捕获了当次渲染的 count 值。当 effect 被执行时,它使用的就是这个捕获的值。
  3. 最新的状态值:由于每次渲染都会生成新的 count,useEffect 中的函数总是能够获取到最新的 count 值。

useLayoutEffect 与 useEffect

1. useLayoutEffect:

在浏览器完成布局和绘制之前同步执行。
适用于需要读取布局信息并同步修改 DOM 的场景。
会阻塞浏览器绘制,影响性能,谨慎使用。

2. useEffect:

在浏览器绘制之后异步执行。
不会阻塞渲染,更常用。
示例场景:

使用 useLayoutEffect:测量 DOM 元素的尺寸或位置,然后立即修改布局。

createRef和useRef

1. createRef

创建方式:React.createRef()。

适用于:主要在 类组件(Class Components) 中使用。

示例:

import React from 'react';class MyComponent extends React.Component {constructor(props) {super(props);this.myRef = React.createRef();}componentDidMount() {// 通过 this.myRef.current 访问 DOM 元素或子组件实例console.log(this.myRef.current);}render() {return <div ref={this.myRef}>Hello World</div>;}
}

每次调用 createRef() 都会返回一个新的 Ref 对象。这意味着如果在函数组件中使用 createRef,每次渲染都会创建一个新的 Ref,而不是持久化的。
适用于类组件:在类组件的构造函数中创建一次 Ref,并在整个组件生命周期中保持一致。

2. useRef

创建方式:const refContainer = useRef(initialValue)。

适用于:函数组件(Function Components),因为它是一个 Hook。

示例:

import React, { useRef, useEffect } from 'react';function MyComponent() {const myRef = useRef(null);useEffect(() => {// 通过 myRef.current 访问 DOM 元素或保存任何可变值console.log(myRef.current);}, []);return <div ref={myRef}>Hello World</div>;
}

useRef 返回的 Ref 对象在整个组件生命周期中是持久的。无论组件如何重新渲染,useRef 返回的对象始终指向同一个引用。
不仅可以用于获取 DOM 元素,还可以用于保存任意可变值,类似于在类组件中使用实例属性。
不会在组件重新渲染时重新初始化。

特性对比

特性createRefuseRef
适用组件类型类组件(Class Components)函数组件(Function Components)
调用时机通常在构造函数中调用一次在函数组件内的任意位置(遵循 Hook 规则)
每次渲染是否创建新 Ref是,每次调用都会创建新的 Ref 对象否,useRef 返回的对象在整个生命周期中保持不变
用途获取 DOM 元素或子组件实例获取 DOM 元素、保存可变值、存储任何可变数据
可持久化的可变值否,主要用于引用 DOM 或组件实例是,可用于存储任意可变值,不会触发重新渲染

相关文章:

React的基础API介绍(一)

目录 useEffect1. 替代生命周期方法2. 副作用管理3. 依赖项数组4. 多次使用5. 与闭包配合6. 支持异步操作7. 减少样板代码 注意事项useEffetct是如何拿到变量count最新的值&#xff1f;1. 每次渲染都会创建新的函数作用域2. 闭包捕获最新的状态值3. useEffect 的执行时机 useLa…...

【Electron】总结:如何创建Electron+Element Plus的项目

我将结合官网手册与AI问到的信息&#xff0c;直接给出步骤&#xff0c;与命令。 一、准备环境 首先在C盘Users&#xff0c;你的登录的账号名文件夹下&#xff0c;编辑.npmrc文件。添加镜像地址。 如果使用了yarn&#xff0c;则是.yarnrc。可以全部都配置。 npm install -g …...

从依托指标字典到 NoETL 自动化指标平台,指标口径一致性管理的进阶

今天&#xff0c;我们一起来梳理和盘点下不同代际指标平台如何实现指标口径一致性管理&#xff1a; 第一代&#xff1a;指标口径登记与管理 第一代指标平台聚焦于指标口径的登记与管理&#xff0c;依托指标字典实现企业指标口径的有效检索与管理功能。 此阶段&#xff0c;业…...

嵌入式面试题练习 - 2024/11/15

欢迎找我进行职业规划&#xff0c;超值的自我投资 -> 嵌入式软件工程师一对一指导 1.设有定义char *p[]{"Shanghai","Beijing","Honkong"};则结果为j字符的表达式是&#xff08;&#xff09; A *p[1] 3 B *(p[1] 3) C *(p[3] 1) D p[3] […...

分析http话术异常挂断原因

用户反馈在与机器人通话时&#xff0c;自己明明有说话&#xff0c;但是通话还是被挂断了&#xff0c;想知道原因。 分析日志 我们根据用户提供的freeswitch日志分析&#xff1a;发现是因为超时导致话术执行hangup动作&#xff0c;结束了通话。 从这一行向上分析日志&#xff…...

云岚到家 秒杀抢购

目录 秒杀抢购业务特点 常用技术方案 抢券 抢券界面 进行抢券 我的优惠券列表 活动查询 系统设计 活动查询分析 活动查询界面显示了哪些数据&#xff1f; 面向高并发如何提高活动查询性能&#xff1f; 如何保证缓存一致性&#xff1f; 数据流 Redis数据结构设计 如…...

【WPF】Prism库学习(一)

Prism介绍 1. Prism框架概述&#xff1a; Prism是一个用于构建松耦合、可维护和可测试的XAML应用程序的框架。它支持WPF、.NET MAUI、Uno Platform和Xamarin Forms等多个平台。对于每个平台&#xff0c;Prism都有单独的发布版本&#xff0c;并且它们在不同的时间线上独立开发。…...

0 -vscode搭建python环境教程参考(windows)

引用一篇非常详细的vscode搭建python环境教程 链接&#xff1a;vscode安装以及配置Python基本环境 以下是VSCode和PyCharm的对比 个人更建议使用VSCode Visual Studio Code (VSCode) Visual Studio Code 是由微软开发的一款免费、开源的轻量级代码编辑器。它支持多种编程语…...

Uniapp 引入 Android aar 包 和 Android 离线打包

需求&#xff1a; 原生安卓 apk 要求嵌入到 uniapp 中&#xff0c;并通过 uniapp 前端调起 app 的相关组件。 下面手把手教你&#xff0c;从 apk 到 aar&#xff0c;以及打包冲突到如何运行&#xff0c;期间我所遇到的问题都会 一 一 进行说明&#xff0c;相关版本以我文章内为…...

10款高效音频剪辑工具,让声音编辑更上一层楼。

音频剪辑在音频&#xff0c;视频&#xff0c;广告制作&#xff0c;游戏开发&#xff0c;广播等领域中都有广泛的应用。通过音频剪辑&#xff0c;创作者可以通将不同的音频片段进行剪切、拼接、混音等操作&#xff0c;创作出风格各异的音乐作品。如果你也正在为音频创作而努力的…...

Javascript——设计模式(一)

Javascript常见设计模式-CSDN博客 设计模式专栏内容总结-CSDN博客 C#编程思想——设计模式-CSDN博客 设计模式概述及其作用 设计模式&#xff08;Design Pattern&#xff09;是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式的主要目的是为…...

Hybird和WebView

在移动端Hybrid开发模式下&#xff0c;iOS和Android应用都可以通过一种共享代码的方式&#xff0c;利用Web技术&#xff08;HTML、CSS、JavaScript&#xff09;和原生应用的功能进行开发。这种方式的主要优点是减少了开发成本&#xff0c;因为大部分代码可以共享&#xff0c;同…...

c++实现中缀表达式 转换为后缀表达式

使用栈来计算后缀表达式的值&#xff1a; 9(3 - 1)*310/2; 后缀表达式&#xff1a;所有的符号都是在运算数字的后面出现&#xff1a; 9 3 1 – 3 * 10 2 / 规则: 中缀表达式转后缀表达式: 1.从左到右遍历中缀表达式的每个数字和符号&#xff0c;若是数字就打印同时入栈数…...

Cisco FMC重置SmartLicense到Evaluatin mode步骤

1 科普&#xff1a; what is FMC full name is Firepower Management Center, 是思科FirePower防火墙的统一管理平台. 能管理ASA不&#xff1f; no&#xff0c;只能管理FTD模式的墙。这里的FTD包括物理机firepower系列运行的FTD&#xff0c;以及FTDv&#xff08;虚拟化版本&a…...

多表查询综合归纳

目录 1. 多表关系 1.1 一对多&#xff08;多对一&#xff09; 1.2 多对多 1.3 一对一 2. 多表查询概述 2.1 熟悉表 2.2 笛卡尔积 2.3 消除笛卡尔积 2.4 多表查询分类 3. 内连接 3.1 隐式内连接 3.2 显式内连接 4. 外连接 4.1 左外连接 4.2 右外连接 5. 自连接 …...

【5.线性表-链式表示-王道课后算法题】

王道数据结构-第二章-链式表示算法题 1.在带头结点的单链表L中&#xff0c;删除所有值为x的结点&#xff0c;并释放其空间&#xff0c;假设值为x的结点不唯一&#xff0c;试编写算法以实现上述操作。2. 试编写在带头结点的单链表L中删除一个最小值结点的高效算法(假设该结点唯一…...

存储过程及练习

1.存储过程 &#x1f4d6;什么是存储过程&#xff1f; 存储过程和函数是事先经过编译并存储在数据库中的一段sql语句集合&#xff0c;调用存储过程函数可以简 化应用开发人员的很多工作&#xff0c;减少数据在数据库和应用服务器之间的传输&#xff0c;对于提高数据处理的 效率…...

【在Linux世界中追寻伟大的One Piece】多路转接epoll

目录 1 -> I/O多路转接之poll 1.1 -> poll函数接口 1.2 -> poll的优点 1.3 -> poll的缺点 1.4 -> poll示例 1.4.1 -> 使用poll监控标准输入 2 -> I/O多路转接之epoll 2.1 -> 初识epoll 2.2 -> epoll的相关系统调用 2.2.1 -> epoll_cre…...

设计模式-参考的雷丰阳老师直播课

一般开发中使用的模式为模版模式策略模式组合&#xff0c;模版用来定义骨架&#xff0c;策略用来实现细节。 模版模式 策略模式 与模版模式特别像&#xff0c;模版模式会定义好步骤定义好框架&#xff0c;策略模式定义小细节 入口类 使用模版模式策略模式开发支付 以上使用…...

Python +Pyqt5 简单视频爬取学习(一)

文章目录 前言 一、演示 二、查找网页视频流的索引文件 三、分析视频流的url和视频流索引文件的差异性 四、判断视频数据是否需要转化为ts 五、判断视频是否被加密&#xff0c;如若被加密&#xff0c;需要先解密 六、合并所有的ts视频&#xff0c;以MP4模式输出完整视频 总结 前…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...