react中ref的使用(useRef,forwardRef,useImperativeHandle,createRef)
文章目录
- 一、什么是ref
- 二、在函数式组件中使用ref
- 1. useRef 获取dom
- 2. forwardRef获取子组件的dom
- 3. useImperativeHandle将某些指定的行为暴露给父组件
- 三、在类组件中使用ref
- 1. createRef
- 2. 回调函数
- 3. 字符串
一、什么是ref
在React中,ref是一个用于访问真实DOM节点或者React组件实例的对象。它允许您在组件中直接操作DOM元素或组件,而无需遵循传统的数据流。
使用ref,您可以:
-
访问和操作DOM:ref允许您通过将ref对象传递给组件中的元素来访问和修改真实的DOM。您可以使用ref来获取输入框的值、改变元素的样式、添加/删除/更新元素等等。
-
访问和调用组件方法:ref允许您访问在组件类上定义的方法。这对于在某些情况下需要从父组件中直接访问子组件的方法非常有用。
-
获取组件实例和进行事件监听:当使用类组件时,ref可以用来获取组件的实例,以便在需要时进行其他操作。您还可以使用ref来进行事件监听,例如在某个特定的事件发生时执行某些操作。
需要注意的是,在大多数情况下,最好遵循React的数据流原则,尽量避免直接操作DOM或访问子组件的方法。只有当没有其他合适的选择并且确实需要这样做时,才应该使用ref。因为直接操作DOM或访问子组件的方法可能会破坏组件的封装性和可重用性。
二、在函数式组件中使用ref
1. useRef 获取dom
在React中,函数式组件使用ref属性可以获取到组件的实例或者某个Dom元素的引用。使用ref可以让你更方便地控制组件或Dom元素,并且可以在需要的时候访问和修改它们的属性和方法。
要在函数式组件中使用ref,你可以使用React提供的useRef钩子函数。举一个例子,假设我们有一个函数式组件MyComponent,其中包含了一个input元素:
import React, { useRef } from 'react';const MyComponent = () => {const inputRef = useRef(null);const handleClick = () => {// 使用 useRef 返回的 ref 对象来访问 input 的属性和方法console.log(inputRef.current.value);inputRef.current.focus();};return (<div><input ref={inputRef} type="text" /><button onClick={handleClick}>Focus Input</button></div>);
};export default MyComponent;
上述例子中,我们使用useRef钩子函数来创建了一个名为inputRef的引用。我们将这个引用传递给了input元素的ref属性,这样就可以通过inputRef.current来获取该input的引用。
在函数式组件的handleClick函数中,我们可以通过inputRef.current访问到input元素并获取到它的值。我们还可以使用inputRef.current.focus()来让input元素获得焦点。
通过使用ref,我们可以方便地操纵组件或Dom元素,进行一些需要访问或修改属性和方法的操作。
注意,ref只能在函数式组件中使用,并且不能在函数式组件的子组件上使用
2. forwardRef获取子组件的dom
在React中,函数式组件的子组件上可以使用forwardRef来使用ref。forwardRef函数可以将ref传递给子组件,从而在子组件中使用ref。
下面是一个示例,展示了如何在函数式组件的子组件中使用ref:
import React, { forwardRef } from 'react';// 子组件
const ChildComponent = forwardRef((props, ref) => {return (<input type="text" ref={ref} />);
});// 父组件
const ParentComponent = () => {// 创建一个refconst inputRef = React.createRef();// 使用ref传递给子组件return (<div><ChildComponent ref={inputRef} /><button onClick={() => inputRef.current.focus()}>聚焦输入框</button></div>);
};export default ParentComponent;
在上面的例子中,ChildComponent是一个函数式组件,通过将ref作为forwardRef的第二个参数,将其传递给内部的input元素。然后,可以在ParentComponent中创建一个ref并将其传递给ChildComponent。这样,我们就可以在父组件中操作子组件的input元素,例如调用focus()方法。
在按钮的onClick事件处理函数中,我们可以通过inputRef.current来获得子组件的input元素,并调用它的focus()方法将焦点聚焦到输入框上。
3. useImperativeHandle将某些指定的行为暴露给父组件
在React中,通过使用useImperativeHandle钩子函数,函数式组件可以将某些指定的行为暴露给父组件。这在一些情况下非常有用,例如限制某些DOM行为,让父组件能够直接操作该组件的某些功能。
下面是一个例子,演示如何使用useImperativeHandle来限制DOM行为:
import React, { useRef, useImperativeHandle, forwardRef } from 'react';// 子组件
const ChildComponent = forwardRef((props, ref) => {const childRef = useRef(null);// 定义待暴露的函数useImperativeHandle(ref, () => ({// 在这里暴露特定的DOM行为focus: () => {childRef.current.focus();},// 在这里暴露特定的DOM行为blur: () => {childRef.current.blur();}}));return <input ref={childRef} />;
});// 父组件
const ParentComponent = () => {const childRef = useRef(null);const handleFocus = () => {childRef.current.focus(); // 子组件的focus函数被父组件调用};const handleBlur = () => {childRef.current.blur(); // 子组件的blur函数被父组件调用};return (<div><ChildComponent ref={childRef} /><button onClick={handleFocus}>Focus</button><button onClick={handleBlur}>Blur</button></div>);
};export default ParentComponent;
在上面的例子中,ChildComponent是一个简单的函数式组件,它包含了一个<input>元素。通过使用useImperativeHandle钩子函数,并将ref作为第一个参数传递进去,我们可以定义需要暴露给父组件的函数(在这里是focus和blur)。这意味着父组件可以通过ref引用子组件,然后直接调用子组件的focus和blur函数。
在ParentComponent中,通过使用useRef来创建一个childRef引用。然后,在handleFocus和handleBlur函数中,通过childRef.current来访问ChildComponent函数组件的focus和blur函数,从而直接操控子组件的DOM行为。
这样,我们就可以在父组件中通过按钮点击来控制子组件的DOM行为,实现了对DOM行为的限制。
三、在类组件中使用ref
1. createRef
在类式组件中,可以使用React.createRef()来创建一个ref对象,然后将该ref对象附加到component的一个元素上,通过ref对象可以引用该元素并对其进行操作。
下面是一个使用ref的示例:
import React from "react";class MyComponent extends React.Component {constructor(props) {super(props);this.myDivRef = React.createRef(); // 创建一个ref对象}handleClick = () => {this.myDivRef.current.style.backgroundColor = "blue"; // 使用ref对象引用元素并对其进行操作}render() {return (<div><div ref={this.myDivRef}>Hello, world!</div> {/* 将ref对象附加到元素上 */}<button onClick={this.handleClick}>Change Color</button></div>);}
}export default MyComponent;
在上面的示例中,我们首先在类的构造函数中创建一个ref对象myDivRef。然后,通过将myDivRef作为<div>元素的ref属性值,我们可以将ref对象附加到这个元素上。在handleClick方法中,我们通过this.myDivRef.current引用该元素并改变其背景颜色为蓝色。
这样,当点击按钮时,就会调用handleClick方法,从而改变被ref引用的<div>元素的背景颜色。
2. 回调函数
通过回调函数来设置ref,在回调函数中将DOM元素分配给组件的实例属性。在组件的实例中,可以通过属性来访问该DOM元素。
import React, { Component } from 'react';class ExampleComponent extends Component {constructor(props) {super(props);this.myRef = null;this.setRef = element => {this.myRef = element;};}componentDidMount() {console.log(this.myRef); // 访问DOM元素}render() {return <div ref={this.setRef}>Example</div>;}
}
3. 字符串
使用字符串的ref属性来获取DOM元素。这种方式在React v16.3之前是支持的,但在较新的版本中已经过时,不建议使用。
import React, { Component } from 'react';class ExampleComponent extends Component {componentDidMount() {console.log(this.refs.myRef); // 访问DOM元素}render() {return <div ref="myRef">Example</div>;}
}
相关文章:
react中ref的使用(useRef,forwardRef,useImperativeHandle,createRef)
文章目录 一、什么是ref二、在函数式组件中使用ref1. useRef 获取dom2. forwardRef获取子组件的dom3. useImperativeHandle将某些指定的行为暴露给父组件 三、在类组件中使用ref1. createRef2. 回调函数3. 字符串 一、什么是ref 在React中,ref是一个用于访问真实DO…...
正点原子嵌入式linux驱动开发——Linux USB驱动
USB是很常用的接口,目前大多数的设备都是USB接口的,比如鼠标、键盘、USB摄像 头等,在实际开发中也常常遇到USB接口的设备,本章就来学习一下如何使能Linux内核自带的USB驱动。这里不会具体学习USB的驱动开发。 USB接口简介 什么是…...
(四)docker:为mysql和java jar运行环境创建同一网络,容器互联
看了很多资料,说做互联的一个原因是容器内ip不固定,关掉重启后如果有别的容器启动,之前的ip会被占用,所以做互联创建一个网络,让几个容器处于同一个网络,就可以互联还不受关闭再启动ip会改变的影响…...
【kafka】记一次kafka基于linux的原生命令的使用
环境是linux,4台机器,版本3.6,kafka安装在node 1 2 3 上,zookeeper安装在node2 3 4上。 安装好kafka,进入bin目录,可以看到有很多sh文件,是我们执行命令的基础。 启动kafka,下面的…...
C语言或C++结构体及其变量的创建方式汇总
第一种: struct 结构体类型名{ 任意类型 变量; }; 结构体类型名 *结构体变量new 结构体类型名; #include<bits/stdc.h> using namespace std; struct LNode {int data;struct LNode *next; }; /*void PutElem(LNode *t){while(t->next!NULL){…...
mysql之基础语句
数据库的列类型 int:整型 用于定义整数类型的数据 float:单精度浮点4字节32位 准确表示到小数点后六位 double:双精度浮点8字节64位 char:固定长度的字符类 用于定义字符类型数据&…...
Sentinel 哨兵数据 更新下载地址 2023年11月
1. 欧空局官方下载 2023年11月开始,原来欧空局的下载地址和应用有了变化,现在迁移到以下新地址下载: https://dataspace.copernicus.eu/ 我这边测试需要重新注册用户才能进行登录和使用,界面使用和之前差不多,具体操作…...
动态路由协议OSPF项目部署(二)
1. 静态和动态路由的区别; 2. OSPF协议通信过程与部署; 3. OSPF协议在项目上的应用场景 - OSPF - 开放式最短路径优先 - 一个动态路由协议 - 路由器转发数据 - 路由器需要一张地图 - 路由表 - 路由表如何构建的? - 依靠手动 或…...
winscp文件增量同步到linux服务器
一,点击同步 场景:在做服务器迁移的时候,文件好几十个G一天也迁移不完,每天还有增量的文件,先全量同步一次,然后再用增量同步,然后你用winscp的同步工具,进增量同步。 将本地文件同…...
足足68个!Python函数合集请收好!
内置函数就是python给你提供的, 拿来直接用的函数,比如print.,input等。 #68个内置函数 # abs() dict() help() min() setattr() # all() dir() hex() next() sli…...
vue2.0 打包,nginx部署
1、修改这里为空 否则报错:vue is undefined 2、修改为hash,重点:打包dist文件运行,必须这样 3、安装ngnix,重点:使用node的包:httpserve,失败 4、重点:配置代理转发 前端…...
微服务架构之路1,服务如何拆分?使用微服务的注意事项?
目录 一、前言二、单体服务的弊端三、微服务化四、服务如何拆分?五、使用微服务的注意事项1、服务如何定义2、服务如何发布和订阅3、服务如何监控4、服务如何治理5、故障如何定位 大家好,我是哪吒。 一、前言 微服务已经是Java开发的必备技能ÿ…...
解决Mac电脑音乐显示歌名的乱码问题
最近想听「万能青年旅店」的歌,结果在Mac电脑的「音乐」里面打开后是乱码。 【原因】(求助于chatGPT) 乱码问题可能是由于MP3文件的元数据(比如歌曲名、艺术家、专辑等信息)的编码问题导致的。如果这些信息是用非标准的或者不兼容的字符编码…...
赢在电商设计!2024年最新电商设计实战技巧盘点
双十一、双十二、黑五的电商大促即将轮番将至,电商运营人迎来大忙季,选品、直播、采购入库、售后……各种环节都是影响电商转化的关键因素,而电商设计作为打通这些环节,打造高转化率电商平台的关键要素,能够吸引用户注…...
约数之和 (普通快速幂求逆元做法)
假设现在有两个自然数 A 和 B,S 是 AB 的所有约数之和。 请你求出 Smod9901 的值是多少。 输入格式 在一行中输入用空格隔开的两个整数 A 和 B 。 输出格式 输出一个整数,代表 Smod9901 的值。 数据范围 0≤A,B≤5107 输入样例: …...
每日一题(LeetCode)----二分查找(三)
每日一题(LeetCode)----二分查找(三) 1.题目(69. x 的平方根 ) 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 **注意…...
使用 TensorFlow FasterRCNN 网络进行目标检测
目录 描述 此示例的工作原理 处理输入图形 数据准备 sampleUffFasterRCNN 插件 验证输出 TensorRT API 层和操作 TensorRT API 层和操作 先决条件 运行示例 示例 --help 选项 附加资源 许可 变更记录 已知问题 本示例,sampleUffFasterRCNN࿰…...
数据结构——顺序表(SeqList)
目录 1. 顺序表介绍 2. 顺序表工程 2.1 顺序表定义 2.1.1 静态顺序表 2.1.2 动态顺序表 2.2顺序表接口 2.2.1 顺序表初始化 2.2.2 顺序表打印 2.2.3 顺序表销毁 2.2.4 顺序表数据插入 2.2.4.1 容量检查 2.2.4.2 顺序表尾插 2.2.4.3 顺序表头插 2.2.4.4 顺序表随机…...
Uni-App 快捷登录
uniapp 实现一键登录前置条件: 开通uniCloud, 开通一键登录功能参考的文档 : 官网 - 一键登录uniapp指南 : https://uniapp.dcloud.net.cn/univerify.html#%E6%A6%82%E8%BF%B0 官网 - 一键登录开通指南 : https://ask.dcloud.net.cn/article/37965 官网 - unicloud使用指南 htt…...
DbUtils + Druid 实现 JDBC 操作 --- 附BaseDao
文章目录 Apache-DBUtils实现CRUD操作1 Apache-DBUtils简介2 主要API的使用2.1 DbUtils2.2 QueryRunner类2.3 ResultSetHandler接口及实现类 3 JDBCUtil 工具类编写3.1 导包3.2 编写配置文件3.3 编写代码 4 BaseDao 编写 Apache-DBUtils实现CRUD操作 1 Apache-DBUtils简介 com…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
