react hooks之useRef和useImperativeHandle
为什么这两个一起写,是因为这两个关联性很大,逐一介绍。
一:useRef
1、作用:用于在函数组件中创建一个持久化的引用变量。这个引用变量可以在组件的多次渲染之间保持不变,并且可以访问和修改 DOM 元素或其他组件实例的实例变量。
2、示例
import React, { useState, useRef } from 'react';function TextInput() {const [value, setValue] = useState('');const inputRef = useRef(null);function focusInput() {inputRef.current.focus();}return (<div><input type="text" value={value} onChange={(e) => setValue(e.target.value)} ref={inputRef} /><button onClick={focusInput}>Focus Input</button></div>);
}function App() {return <TextInput />;
}
在这个示例中,我们首先使用 useState
Hook 创建了一个名为 value
的状态变量,它保存了输入框中的值。然后,我们使用 useRef
Hook 创建了一个名为 inputRef
的引用变量,并将其初始化为 null
。
在输入框标签中,我们使用了 ref={inputRef}
属性将 inputRef
和输入框绑定起来。这样,我们就可以在组件中的其他地方访问和修改输入框元素的属性。
在 focusInput
函数中,我们使用了 inputRef.current
来获取输入框元素,并调用了 focus()
方法来聚焦输入框。
最后,在 TextInput
组件中,我们渲染了一个输入框和一个按钮。当用户点击按钮时,它会调用 focusInput
函数,将焦点聚焦到输入框上。
这是 useRef
的基本用法。通过使用 useRef
,你可以在函数组件中创建一个持久化的引用变量,并访问和修改 DOM 元素或其他组件实例的实例变量。
(示例2)
import React, { useEffect, useRef } from 'react';function Timer() {const timerRef = useRef(null);useEffect(() => {// 在组件挂载时启动定时器timerRef.current = setInterval(() => {console.log('Timer tick');}, 1000);// 在组件卸载时清除定时器return () => {clearInterval(timerRef.current);};}, []);return (<div><h1>Timer</h1></div>);
}function App() {return <Timer />;
}
在这个示例中,我们使用 useRef
创建了一个名为 timerRef
的引用变量,并将其初始化为 null
。
在 useEffect
钩子中,我们使用 timerRef.current
来获取当前的定时器引用。当组件挂载时,我们通过 setInterval
创建一个定时器,并将其赋值给 timerRef.current
。定时器每隔一秒钟输出 "Timer tick"。
同时,我们还在 useEffect
中返回一个清理函数,它会在组件卸载时执行。在清理函数中,我们使用 clearInterval
来清除定时器,以防止内存泄漏。
最后,在 Timer
组件中,我们渲染了一个标题标签。但重点是,我们在组件的生命周期方法中使用了 useEffect
和 useRef
来启动和清除定时器。
这是另一个 useRef
的例子,展示了它如何用于在函数组件中引用和管理副作用.
3、总结:
通过上面两个示例,可以了解到,useref有两个作用:
1、保存 DOM 元素的引用:获取组件的属性等操作
2、缓存组件状态:简单的理解为,和usestate不同的是,useRef
返回的 ref
对象可以在组件的每次渲染过程中保持不变,即使组件重新渲染,它也不会被重新赋值。
二、useImperativeHandle
1、作用:用于在函数组件中自定义向父组件暴露的实例值和方法。通常情况下,React 推荐使用 props 来进行组件之间的通信,但有时候我们可能需要在函数组件中使用类似于 Class 组件中的实例方法和属性。
2、用法:useImperativeHandle
接受两个参数:ref
和一个回调函数。回调函数会接收一个参数,即父组件传递给子组件的 ref
对象。在回调函数中,我们可以定义这个 ref
对象所暴露出来的实例值和方法。
3、示例
import React, { useRef, useImperativeHandle, forwardRef } from 'react';const ChildComponent = forwardRef((props, ref) => {const inputRef = useRef();useImperativeHandle(ref, () => ({focus: () => {inputRef.current.focus();},getValue: () => {return inputRef.current.value;}}));return <input type="text" ref={inputRef} />;
});function ParentComponent() {const childRef = useRef();function handleClick() {childRef.current.focus();const value = childRef.current.getValue();console.log('Input value:', value);}return (<div><ChildComponent ref={childRef} /><button onClick={handleClick}>Focus Input and Get Value</button></div>);
}
上面的示例中,我们创建了一个 ChildComponent
组件,并使用 useRef
声明了一个 childRef
引用。然后,在 useImperativeHandle
的回调函数中,我们定义了要向父组件暴露的两个实例方法:focus
和 getValue
。在 focus
方法中,我们通过 childRef.current
来访问子组件的 DOM 元素,并使其获取焦点。在 getValue
方法中,我们同样通过 childRef.current
来获取子组件输入框的值。
在父组件中,我们使用 React.forwardRef
包裹了 ChildComponent
,以便能够接收父组件传递的 ref
。然后,我们创建了一个 childRef
引用,将其传递给 ForwardedChildComponent
。当点击按钮时,我们调用 childRef.current
上的 focus
方法和 getValue
方法,并输出输入框的值。
总结:子组件想暴露给父组件什么完全由子组件决定。和vue中的ref不同。
相关文章:
react hooks之useRef和useImperativeHandle
为什么这两个一起写,是因为这两个关联性很大,逐一介绍。 一:useRef 1、作用:用于在函数组件中创建一个持久化的引用变量。这个引用变量可以在组件的多次渲染之间保持不变,并且可以访问和修改 DOM 元素或其他组件实例…...

scala方法与函数
定义方法定义函数方法和函数的区别scala的方法函数操作 1.9 方法与函数 1.9.1 定义方法 定义方法的基本格式是: def 方法名称(参数列表):返回值类型 方法体 def add(x: Int, y: Int): Int x y println(add(1, 2)) // 3 //也…...

前端框架(Front-end Framework)和库(Library)的区别
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

mysql原理--B+树索引的使用
1.索引的代价 在介绍如何更好的使用索引之前先要了解一下使用这玩意儿的代价,它在空间和时间上都会拖后腿: (1). 空间上的代价 这个是显而易见的,每建立一个索引都要为它建立一棵 B 树,每一棵 B 树的每一个节点都是一个数据页&…...
Android : Room 数据库的基本用法 —简单应用_三_版本
在实体类中添加了新字段: Entity(tableName "people") public class People {//新添加的字段private String email;public String getEmail() {return email;}public void setEmail(String email) {this.email email;}} 再次编译启动时会报错…...

微服务网关组件Gateway实战
1. 需求背景 在微服务架构中,通常一个系统会被拆分为多个微服务,面对这么多微服务客户端应该如何去调用呢?如果根据每个微服务的地址发起调用,存在如下问题: 客户端多次请求不同的微服务,会增加客户端代码…...
目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】三维重建(补充篇)
目录 前言 算法原理 三维重建意义 三维重建定义 常见的三维重建表达方式...

关于uniapp X 的最新消息
uni-app x 是什么? uni-app x,是下一代 uni-app,是一个跨平台应用开发引擎。 uni-app x 没有使用js和webview,它基于 uts 语言。在App端,uts在iOS编译为swift、在Android编译为kotlin,完全达到了原生应用的…...
spark从表中采样(随机选取)一定数量的行
在Spark SQL中,你可以使用TABLESAMPLE来按行数对表进行采样。以下是使用TABLESAMPLE的示例: SELECT * FROM table_name TABLESAMPLE (1000 ROWS);在这个示例中,table_name是你要查询的表名。TABLESAMPLE子句后面的(1000 ROWS)表示采样的行数…...

java定位系统源码,UWB技术的无线定位系统源码
UWB技术是一种传输速率高,发射功率较低,穿透能力较强并且是基于极窄脉冲的无线技术。UWB最优的应用环境是室内或者相对密闭的空间,有着厘米级的定位精度,不仅可以非常精准地进行位置跟踪,还可以快速地进行数据传输。 智…...

阿里云sls日志服务如何查某个具体字段的平均数
1: 需求: 查询线上某个接口(如:list_new)的成功率和时延 查接口时延的写法在网上找了一堆,都是语法错误,最后在阿里云官方api找到了正确的 2:贴一下阿里云官方文档: 聚…...
Java八股文面试全套真题【含答案】- Maven篇
以下是一些关于Maven的经典面试题以及它们的答案: 什么是Maven? Maven是一个项目管理工具,用于构建、发布和管理Java项目。它提供了一种标准化的项目结构、依赖管理和构建过程。Maven的核心概念是什么? Maven的核心概念包括POM文…...

从零构建属于自己的GPT系列6:模型本地化部署2(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:数据预处理 从零构建属于自己的GPT系列2:模型训…...

不同品牌的手机如何投屏到苹果MacBook?例如小米、华为怎样投屏比较好?
习惯使用apple全家桶的人当然知道苹果手机或iPad可以直接用airplay投屏到MacBook。 但工作和生活的多个场合里,并不是所有人都喜欢用同一品牌的设备,如果同事或同学其他品牌的手机需要投屏到MacBook,有什么方法可以快捷实现? 首先…...
路由和网络周期
### 路由(Routing): 1. **路由的概念:** 路由是用于确定用户在网站或应用程序中所处位置的机制。它可以将不同的 URL 映射到对应的页面或视图组件,使得用户可以通过不同的 URL 访问不同的内容。 2. **路由器…...

【算法与数据结构】332、LeetCode重新安排行程
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题比较属于困难题目,难点在于完成机票、出发机场和到达机场之间的映射关系,再…...
阶段五:深度学习和人工智能(掌握使用TensorFlow或PyTorch进行深度学习)
掌握使用TensorFlow或PyTorch进行深度学习需要具备一定的编程基础和数学基础,包括编程语言、数据结构、算法、线性代数、概率论和统计学等方面的知识。以下是掌握使用TensorFlow或PyTorch进行深度学习的一些基本要求: 了解深度学习的基本概念和原理&…...

DevEco Studio IDE 创建项目时候配置环境
DevEco Studio IDE 创建项目时候配置环境 一、安装环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、在配置向导的时候意外关闭配置界面该如何二次配置IDE环境。 打开IDE的界面是这样的。 点击Create Project进行环境配置。 点击OK后出现如…...

HTML面试题---专题二
文章目录 一、前言二、解释input标签中占位符属性的用途三、如何在 HTML 中设置复选框或单选按钮的默认选中状态?四、表单输入字段中必填属性的用途是什么?五、如何使用 HTML 创建表格?六、解释a标签中目标属性的用途七、如何创建一个点击后会…...
K12484 银行排队(bank)
题目描述 K个人来银行排队办理业务,银行有n个窗口可以同时办理,每个窗口允许有m个人排队,其余的人在银行大厅等待。当某个窗口排队人数少于m时,在大厅等待的人可进入该窗口排队。每个人都有自己要办的业务,每个业务要…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...