React第十七章(useRef)

useRef

当你在React中需要处理DOM元素或需要在组件渲染之间保持持久性数据时,便可以使用useRef。

import { useRef } from 'react';
const refValue = useRef(initialValue)
refValue.current // 访问ref的值 类似于vue的ref,Vue的ref是.value,其次就是vue的ref是响应式的,而react的ref不是响应式的

通过Ref操作DOM元素

参数
  • initialValue:ref 对象的 current 属性的初始值。可以是任意类型的值。这个参数在首次渲染后被忽略。
返回值
  • useRef返回一个对象,对象的current属性指向传入的初始值。 {current:xxxx}
注意
  • 改变 ref.current 属性时,React 不会重新渲染组件。React 不知道它何时会发生改变,因为 ref 是一个普通的 JavaScript 对象。
  • 除了 初始化 外不要在渲染期间写入或者读取 ref.current,否则会使组件行为变得不可预测。
import { useRef } from "react"
function App() {//首先,声明一个 初始值 为 null 的 ref 对象let div = useRef(null)const heandleClick = () => {//当 React 创建 DOM 节点并将其渲染到屏幕时,React 将会把 DOM 节点设置为 ref 对象的 current 属性console.log(div.current)}return (<>{/*然后将 ref 对象作为 ref 属性传递给想要操作的 DOM 节点的 JSX*/}<div ref={div}>dom元素</div><button onClick={heandleClick}>获取dom元素</button></>)
}
export default App

数据存储

我们实现一个保存count的新值和旧值的例子,但是在过程中我们发现一个问题,就是num的值一直为0,这是为什么呢?

因为等useStateSetCount执行之后,组件会重新rerender,num的值又被初始化为了0,所以num的值一直为0。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {let num = 0let [count, setCount] = useState(0)const handleClick = () => {setCount(count + 1)num = count;};return (<div><button onClick={handleClick}>增加</button><div>{count}:{num}</div></div>);
}export default App;

在这里插入图片描述

如何修改?

我们可以使用useRef来解决这个问题,因为useRef只会在初始化的时候执行一次,当组件reRender的时候,useRef的值不会被重新初始化。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {let num = useRef(0)let [count, setCount] = useState(0)const handleClick = () => {setCount(count + 1)num.current = count;};return (<div><button onClick={handleClick}>增加</button><div>{count}:{num.current}</div></div>);
}export default App;

在这里插入图片描述

实际应用

我们实现一个计时器的例子,在点击开始计数的时候,计时器会每300ms执行一次,在点击结束计数的时候,计时器会被清除。

问题

我们发现,点击end的时候,计时器并没有被清除,这是为什么呢?

原因

这是因为组件一直在重新ReRender,所以timer的值一直在被重新赋值为null,导致无法清除计时器。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {console.log('render')let timer: NodeJS.Timeout | null = nulllet [count, setCount] = useState(0)const handleClick = () => {timer = setInterval(() => {setCount(count => count + 1)}, 300)};const handleEnd = () => {console.log(timer);if (timer) {clearInterval(timer)timer = null}};return (<div><button onClick={handleClick}>开始计数</button><button onClick={handleEnd}>结束计数</button><div>{count}</div></div>);
}export default App;
如何修改?

我们可以使用useRef来解决这个问题,因为useRef的值不会因为组件的重新渲染而改变。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {console.log('render')let timer = useRef<null | NodeJS.Timeout>(null)let [count, setCount] = useState(0)const handleClick = () => {timer.current = setInterval(() => {setCount(count => count + 1)}, 300)};const handleEnd = () => {if (timer.current) {clearInterval(timer.current)timer.current = null}};return (<div><button onClick={handleClick}>开始计数</button><button onClick={handleEnd}>结束计数</button><div>{count}</div></div>);
}export default App;

注意事项

  1. 组件在重新渲染的时候,useRef的值不会被重新初始化。

  2. 改变 ref.current 属性时,React 不会重新渲染组件。React 不知道它何时会发生改变,因为 ref 是一个普通的 JavaScript 对象。

  3. useRef的值不能作为useEffect等其他hooks的依赖项,因为它并不是一个响应式状态。

  4. useRef不能直接获取子组件的实例,需要使用forwardRef。

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

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

相关文章

xtu oj 制药

文章目录 回顾前言代码思路 回顾 AB III问题 H: 三角数问题 G: 3个数等式 数组下标查询&#xff0c;降低时间复杂度1405 问题 E: 世界杯xtu 数码串xtu oj 神经网络xtu oj 1167 逆序数&#xff08;大数据&#xff09;xtu oj 原根xtu oj 不定方程的正整数解xtu oj 最多的可变换字…

【Linux】VMware 安装 Ubuntu18.04.2

ISO镜像安装步骤 选择语言 English 选择键盘布局 English 选择系统 Ubuntu 虚拟机网卡地址&#xff0c;默认即可 代理地址&#xff0c;默认空即可 镜像地址&#xff0c;修改成阿里云地址 选择第二项&#xff0c;LVM 磁盘扩容技术 第一块硬盘名sda&#xff0c;默认…

Java项目实战II基于微信小程序的跑腿系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的现代生活中&…

透彻理解并解决Mockito模拟框架的单元测试无法运行的问题

本篇的实例基于Maven IDE (VS Code) 运行 在VS Code 运行的时候&#xff0c; 不需要在pom.xml 中添加任何插件就可以在测试类中看到如下的绿色按钮&#xff0c;单击就可以运行使用Mockito 注解 ExtendWith(MockitoExtension.class) 或是 Mockito 代码方式的测试。 不使用注…

CUDA学习笔记(1):安装和起步-1

CUDA安装和起步 写在前面硬件的准备学习的目的Pytorch学习CUDA方向 CUDA相关的书寻找CUDA的示例 安装Vsual Studio 2019下载CUDA和安装首先检查&#xff0c;自己的电脑是否已装过CUDA&#xff08;读作&#xff1a;kuda&#xff09;查看cuda-samples README.md&#xff0c;要求的…

获取pdf文件文字图片内容以及在PDF中插入图片

该功能用到如下jar包&#xff1a; //获取图片数据public void huoqu() throws IOException {File file new File("C:\\Users\\xiaomage\\Desktop\\123.pdf");PDDocument document Loader.loadPDF(file);/* PDFTextStripper stripper new PDFTextStripper();String…

【C#】NET 9中LINQ的新特性-CountBy

前言 在 .NET 中,使用 LINQ 对元素进行分组并计算它们的出现次数时,需要通过两个步步骤。首先,使用 GroupBy方法根据特定键对元素进行分类。然后,再计算每个组元素包含个数。而随着 .NET 9 版本发布,引入了一些新特性。其中 LINQ 引入了一种新的方法 CountBy,本文一起来了…

若依集成更好用的easyexcel

背景 若依使用的是apach poi并在此基础上进行封装apach poi的原生的api是很复杂的&#xff0c;若依简化了了此操作apach poi的上传速率和下载速率都是没有优化的&#xff0c;依赖于文件大小的限制在此前提下&#xff0c;如果没法满足客户的需求&#xff08;超大型文件的上传&am…

阿里内部正式开源“Spring Cloud Alibaba (全彩小册)”

年轻的毕业生们满怀希望与忐忑&#xff0c;去寻找、竞争一个工作机会。已经在职的开发同学&#xff0c;也想通过社会招聘或者内推的时机争取到更好的待遇、更大的平台。 然而&#xff0c;面试人群众多&#xff0c;技术市场却相对冷淡&#xff0c;面试的同学们不得不面临着 1 个…

Android问题记录 - Inconsistent JVM-target compatibility detected for tasks

文章目录 前言开发环境问题描述问题分析解决方案补充内容最后 前言 前段时间升级Android Studio后修复了一堆问题&#xff0c;详情请看&#xff1a;Android问题记录 - 适配Android Studio Ladybug/Java 21/AGP 8.0&#xff08;持续更新&#xff09;。我以为问题已经全部解决了…

分布式专题(1)之Redis持久化、主从与哨兵架构详解

一、Redis持久化 1.1 RDB快照&#xff08;snapshot&#xff09; 在默认的情况下&#xff0c;Redis将内存数据快照保存名字为&#xff1a;dump.rdb的二进制文件中&#xff0c;当然你在配置文件redis.conf中修改对应的二进制文件名。 redis开启RDB快照&#xff0c;可以在redis中…

Y20030053 JSP+SSM+MYSQL+LW+旅游系统的设计与实现 源码 配置 文档 全套资料

旅游系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 摘 要 随着旅游业的蓬勃发展和人们对休闲度假需求的不断增加&#xff0c;旅游业管理面临着越来越多的挑战。为了提高管理效率、优化客户体验并增强市场竞争力&#xff0c;本文介绍…

TypeScript进阶

Typescript进阶 基础知识 JavaScript 的核心特点就是灵活&#xff0c;但随着项目规模的增大&#xff0c;灵活反而增加开发者的心智负担。例如在代码中一个变量可以被赋予字符串、布尔、数字、甚至是函数&#xff0c;这样就充满了不确定性。而且这些不确定性可能需要在代码运行…

github操作学习笔记

git开源的分布式版本控制系统&#xff1a; 每次修改文件提交后&#xff0c;都会自动创建一个项目版本 查看git版本看有没有安装成功&#xff1a;git --version 把默认编辑器设置成vim&#xff1a;git config --global core.editor "vim" 1、设置昵称和邮箱&#xff…

QT 多级嵌套结构体,遍历成员--半自动。<模板+宏定义>QTreeWidget树结构显示

Qt的QTreeWidget来显示嵌套结构体的成员&#xff0c;并以树形结构展示。 #include <QApplication> #include <QTreeWidget> #include <QTreeWidgetItem> #include <QString> #include <cstdint>// 假设这些是你的结构体定义 struct BaseMeterPa…

简明速通Java接口

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文从代码层面直接整理Java接口 让老油子们无需再理解繁杂的概念了。 Java接口在代码层面是做什么的 说白了老铁&#xff0c;Java的接口就是一个类&#xff0c;这个类中只能声明属性和方法&#xff0c;属性需要…

2.linux中调度kettle

一.准备转换&#xff0c;等会在linux中用 1.添加excel输入组件&#xff0c;并添加对应的文件 2.添加列拆分为多行组件 3.添加文本文件输出组件 4.保存转换 二.linux安装java 1.把jdk-8u144-linux-x64.tar.gz上传到linux的/lx目录下 2. 解压jdk包&#xff0c;然后配置环境变量…

【C#设计模式(19)——备忘录模式(MementoPattern)】

前言 备忘录模式&#xff1a;将想要备份的信息交给备忘录对象来管理。通过设置初始、备份、修改、恢复等状态展示备忘录模式的使用。 代码 //备忘录类 public class Memento {private string state;public string State { get>state;}public Memento(string state){this.st…

如何将CSDN博客下载为PDF文件

1.打开CSDN文章内容 2.按键盘上的f12键&#xff08;或者右键—审查元素&#xff09;进入浏览器调试模式&#xff0c;点击控制台&#xff08;Console&#xff09;进入控制台 3.在控制台输入以下代码&#xff0c;回车 (function(){ $("#side").remove(); $("#…

GWAS分析先做后学

大家好&#xff0c;我是邓飞。 GWAS分析是生物信息和统计学的交叉学科&#xff0c;上可以学习编程&#xff0c;下可以学习统计。对于Linux系统&#xff0c;R语言&#xff0c;作图&#xff0c;统计学&#xff0c;机器学习等方向&#xff0c;都是一个极好的入门项目。生物信息如…