React的基础API介绍(一)

目录

    • useEffect
    • useEffetct是如何拿到变量count最新的值?
    • useLayoutEffect 与 useEffect
    • createRef和useRef

useEffect

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

  1. 替代生命周期方法
    模拟类组件的生命周期:useEffect 可以模拟类组件的 componentDidMount、componentDidUpdate 和 componentWillUnmount 方法,允许在组件的不同阶段执行相应的逻辑。
useEffect(() => {// componentDidMount 和 componentDidUpdate 的逻辑return () => {// componentWillUnmount 的逻辑};
}, [dependencies]);
  1. 副作用管理
    处理副作用:useEffect 在组件渲染后执行,用于处理需要在渲染后发生的副作用,例如更新 DOM、设置订阅、发送网络请求等。

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

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

useEffect(() => {const subscription = someService.subscribe();return () => {subscription.unsubscribe();};
}, []);
  1. 依赖项数组
    精确控制 effect 执行时机:依赖项数组 [dependencies] 允许你指定 effect 何时重新执行。只有当数组中的依赖项发生变化时,effect 才会被触发。空数组的话只执行一次,相当于componentDidMount

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

useEffect(() => {// 仅当 count 变化时执行
}, [count]);
  1. 多次使用
    拆分逻辑:可以在同一个组件中多次使用 useEffect,每个 effect 钩子可以处理不同的副作用逻辑,保持代码清晰。
useEffect(() => {// 处理订阅逻辑
}, []);useEffect(() => {// 处理数据获取逻辑
}, [dataId]);
  1. 与闭包配合
    访问最新的 state 和 props:useEffect 内部的函数会捕获到当前渲染周期的 state 和 props,确保副作用操作基于最新的数据。
  2. 支持异步操作
    处理异步任务:useEffect 可以轻松处理异步操作,如数据获取和定时器。
useEffect(() => {async function fetchData() {const result = await axios.get('/api/data');setData(result.data);}fetchData();
}, []);
  1. 减少样板代码
    简化代码结构:相比于类组件的生命周期方法,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 的场景。
会阻塞浏览器绘制,影响性能,谨慎使用。

  1. 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,并在整个组件生命周期中保持一致。

  1. 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 或组件实例是,可用于存储任意可变值,不会触发重新渲染

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/468900.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用pip安装项目时,遇到以下错误的解决方案:error: [Errno 13] Permission denied

我是在虚拟环境下出现了这个错误 出现这种情况大概率是conda环境没有下载用户路径下的python解释器&#xff0c;你可以使用下面命令来检查 which python3这里如果出现的路径不是你用户目录下的&#xff0c;就是这个原因&#xff0c;你的conda环境在用户目录下&#xff0c;但是…

无人车之定位技术篇

无人车的定位技术是指确定无人车在世界坐标系&#xff08;一般指二维环境&#xff09;中的位置及其本身的姿态的技术。随着技术的不断发展&#xff0c;无人车的定位技术已经实现了多种方法的融合与创新。 一、主要定位技术 GPS定位 原理&#xff1a;基于全球定位系统&#x…

微观经济学速成笔记

需求的收入弹性 需求的收入弹性表示在一定的时期内消费者对某种商品的需求量的变动对于消费者收入量变动的反应程度,供给的收入弹性公式为: 永非证可eM或w-此公-可 根据商品的需求和收入弹性公式&#xff0c;可以将商品分类: em < 0的商品为劣等品(也称低档品)&#xff0c;因…

泷羽sec学习打卡-Windows基础命令2总结篇

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 关于windows的那些事儿-Base2 一、Windows-Base2常见的协议和端口常用的cmd命令渗透写入文件的思路&…

面经—科大讯飞

1extern c 修饰才能使用c在c中 new delete 可以自动判断分配多少空间 形成多态的两个条件&#xff0c;1.继承关系

软考教材重点内容 信息安全工程师 第1章 网络信息安全概述

第 1 章 网络信息安全概述 1.1.1 网络信息安全相关概念 狭义上的网络信息安全特指网络信息系统的各组成要素符合安全属性的要求&#xff0c;即机密性、完整性、可用性、抗抵赖性、可控性。 广义上的网络信息安全是涉及国家安全、城市安全、经济安全、社会安全、生产安全、人身安…

【51单片机】I2C总线详解 + AT24C02

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 AT24C02介绍存储器 I2C总线介绍I2C时序结构数据帧AT24C02数据帧 编程实例 —— 按键控制数据大小&存储器写入读出 AT24C02介绍 …

全球海工供应链,中国建造!第十一届全球FPSOFLNGFSRU大会在上海隆重召开

10月30日-31日&#xff0c;全球海洋工程与高端装备领域的年度国际交流盛会——第十一届全球FPSO&FLNG&FSRU大会暨海上能源全产业链博览会在上海隆重召开&#xff0c;同期举办第七届亚洲海洋风能大会。本次大会暨博览会由上海船舶工业行业协会、上海市工业合作协会、决策…

Linux网络编程——网络字节序和IP地址详解

一、网络字节序 1、大端模式和小端模式 字节序是指多字节数据的存储顺序&#xff0c;在设计计算机系统的时候&#xff0c;有两种处理内存中数据的方法&#xff1a;大端格式、小端格式。 小端格式(Little-Endian)&#xff1a;将低位字节数据存储在低地址&#xff1b; 大端格式(…

解析低代码开发在企业数字化转型中的多重优势

在数字化转型的浪潮中&#xff0c;企业面临着前所未有的机遇和挑战。为了在竞争激烈的市场中脱颖而出&#xff0c;企业需要迅速且高效地构建和更新应用程序&#xff0c;以适应不断变化的业务需求。数字化转型已不再是企业的选择&#xff0c;而是关乎生存和发展的必由之路。在这…

JMeter项目实战

目录 一、流程&#xff1a; 1.接口测试流程&#xff1a; 2.测试数据准备&#xff1a; 3.接口功能测试&#xff1a; 4.自动化测试流程&#xff1a; 5.情景压力测试分析&#xff1a; 6.生成图形化测试报告&#xff1a; 一、流程&#xff1a; 1.接口测试流程&#xff1a; …

SHARE 100M A10风力发电机动态巡检

背景 随着碳中和、碳达峰“3060”目标的提出&#xff0c;“十四五”时期乃至本世纪中叶应对气候变化工作、绿色低碳发展和生态文明建设提出了更高要求。在时代建设的背景下&#xff0c;清洁能源行业蓬勃发展&#xff0c;传统静态巡检模式与高度依赖人力的风机巡检运维手段已经无…

数据分析:宏基因组DESeq2差异分析筛选差异物种

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍原理:计算步骤:结果:加载R包准备画图主题数据链接导入数据Differential abundance (No BP vs 2BP TA)构建`countData`矩阵过滤低丰度物种构建DESeq数据对象DESeq2差异分析画图Di…

Linux进程信号(信号的产生)

目录 什么是信号&#xff1f; 信号的产生 信号产生方式1&#xff1a;键盘 前台进程 后台进程 查看信号 signal系统调用 案例 理解进程记录信号 软件层面 硬件层面 信号产生方式2:指令 信号产生方式3:系统调用 kill系统调用 案例 其他产生信号的函数调用 1.rais…

【ESP】一小时速通入门笔记

【ESP】一小时速通入门笔记 前言: 之前上学时就用过一次esp32, 当时初次使用搭建编译环境费了老大功夫.在我第一篇esp32笔记中也有说明.以至于我好像忘记记录完整的入门笔记了.最近因为工作需要又开始接触esp32才发现,现在已经方便得多了.顺利的话一小时速通. 前排提醒: 本笔记…

22.04Ubuntu---ROS2使用rclcpp编写节点C++

节点需要存在于功能包当中&#xff0c;功能包需要存在于工作空间当中。 所以我们要想创建节点&#xff0c;就要先创建一个工作空间&#xff0c;再创建功能包。 第一步&#xff1a;创建工作空间 mkdir -p chapt2_ws/src/ 第二步&#xff1a;创建example_cpp功能包&#xff0c…

QML项目实战:自定义CheckBox

目录 一.添加模块 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.15 二.自定义CheckBox 1.CheckBox设置 2.勾选框设置 3.标签部分 4. 状态变化处理 5.文本设置 三.效果 1.当enabled为true 2.当enabled为true 3.当…

【Git】Liunx环境下Git的使用:“克隆,提交,推送“

目录 一、常用参数 二、我们为什么要使用Git&#xff1f; 三、创建远程仓库 第一步&#xff1a;创建对应代码托管平台账号。 第二步&#xff1a;在托管平台创建仓库 第三步&#xff1a;完善仓库内容&#xff08;选择性使用&#xff09; 开源和私有 四、克隆远程仓库到本…

《Python网络安全项目实战》项目4 编写网络扫描程序

《Python网络安全项目实战》项目4 编写网络扫描程序 项目4 编写网络扫描程序任务4.1 扫描内网有效IP地址任务描述任务分析任务实施任务拓展 任务4.2 编写端口扫描工具任务描述任务分析任务实施相关知识任务评价任务拓展项目评价 项目4 编写网络扫描程序 许多扫描工具是由Pytho…

软件设计开发规程,制度(word原件)

技术解决方案过程包括&#xff1a; 1、选择最佳解决方案&#xff1b; 2、制定架构设计&#xff1b; 3、制定概要设计&#xff1b; 4、制定详细设计和数据库设计&#xff1b; 5、利用准则进行接口设计&#xff1b; 6、实现设计&#xff1b; 7、进行单元测试&#xff1b; 8、进行…