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

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,您可以:

  1. 访问和操作DOM:ref允许您通过将ref对象传递给组件中的元素来访问和修改真实的DOM。您可以使用ref来获取输入框的值、改变元素的样式、添加/删除/更新元素等等。

  2. 访问和调用组件方法:ref允许您访问在组件类上定义的方法。这对于在某些情况下需要从父组件中直接访问子组件的方法非常有用。

  3. 获取组件实例和进行事件监听:当使用类组件时,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来使用refforwardRef函数可以将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作为第一个参数传递进去,我们可以定义需要暴露给父组件的函数(在这里是focusblur)。这意味着父组件可以通过ref引用子组件,然后直接调用子组件的focusblur函数。

ParentComponent中,通过使用useRef来创建一个childRef引用。然后,在handleFocushandleBlur函数中,通过childRef.current来访问ChildComponent函数组件的focusblur函数,从而直接操控子组件的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中&#xff0c;ref是一个用于访问真实DO…...

正点原子嵌入式linux驱动开发——Linux USB驱动

USB是很常用的接口&#xff0c;目前大多数的设备都是USB接口的&#xff0c;比如鼠标、键盘、USB摄像 头等&#xff0c;在实际开发中也常常遇到USB接口的设备&#xff0c;本章就来学习一下如何使能Linux内核自带的USB驱动。这里不会具体学习USB的驱动开发。 USB接口简介 什么是…...

(四)docker:为mysql和java jar运行环境创建同一网络,容器互联

看了很多资料&#xff0c;说做互联的一个原因是容器内ip不固定&#xff0c;关掉重启后如果有别的容器启动&#xff0c;之前的ip会被占用&#xff0c;所以做互联创建一个网络&#xff0c;让几个容器处于同一个网络&#xff0c;就可以互联还不受关闭再启动ip会改变的影响&#xf…...

【kafka】记一次kafka基于linux的原生命令的使用

环境是linux&#xff0c;4台机器&#xff0c;版本3.6&#xff0c;kafka安装在node 1 2 3 上&#xff0c;zookeeper安装在node2 3 4上。 安装好kafka&#xff0c;进入bin目录&#xff0c;可以看到有很多sh文件&#xff0c;是我们执行命令的基础。 启动kafka&#xff0c;下面的…...

C语言或C++结构体及其变量的创建方式汇总

第一种&#xff1a; struct 结构体类型名{ 任意类型 变量&#xff1b; }; 结构体类型名 *结构体变量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&#xff1a;整型 用于定义整数类型的数据 float&#xff1a;单精度浮点4字节32位 准确表示到小数点后六位 double&#xff1a;双精度浮点8字节64位 char&#xff1a;固定长度的字符类 用于定义字符类型数据&…...

Sentinel 哨兵数据 更新下载地址 2023年11月

1. 欧空局官方下载 2023年11月开始&#xff0c;原来欧空局的下载地址和应用有了变化&#xff0c;现在迁移到以下新地址下载&#xff1a; https://dataspace.copernicus.eu/ 我这边测试需要重新注册用户才能进行登录和使用&#xff0c;界面使用和之前差不多&#xff0c;具体操作…...

动态路由协议OSPF项目部署(二)

1. 静态和动态路由的区别&#xff1b; 2. OSPF协议通信过程与部署&#xff1b; 3. OSPF协议在项目上的应用场景 - OSPF - 开放式最短路径优先 - 一个动态路由协议 - 路由器转发数据 - 路由器需要一张地图 - 路由表 - 路由表如何构建的&#xff1f; - 依靠手动 或…...

winscp文件增量同步到linux服务器

一&#xff0c;点击同步 场景&#xff1a;在做服务器迁移的时候&#xff0c;文件好几十个G一天也迁移不完&#xff0c;每天还有增量的文件&#xff0c;先全量同步一次&#xff0c;然后再用增量同步&#xff0c;然后你用winscp的同步工具&#xff0c;进增量同步。 将本地文件同…...

足足68个!Python函数合集请收好!

内置函数就是python给你提供的, 拿来直接用的函数&#xff0c;比如print.&#xff0c;input等。 #68个内置函数 # abs()   dict()   help()   min()   setattr() # all()   dir()   hex()   next()   sli…...

vue2.0 打包,nginx部署

1、修改这里为空 否则报错&#xff1a;vue is undefined 2、修改为hash&#xff0c;重点&#xff1a;打包dist文件运行&#xff0c;必须这样 3、安装ngnix&#xff0c;重点&#xff1a;使用node的包&#xff1a;httpserve&#xff0c;失败 4、重点&#xff1a;配置代理转发 前端…...

微服务架构之路1,服务如何拆分?使用微服务的注意事项?

目录 一、前言二、单体服务的弊端三、微服务化四、服务如何拆分&#xff1f;五、使用微服务的注意事项1、服务如何定义2、服务如何发布和订阅3、服务如何监控4、服务如何治理5、故障如何定位 大家好&#xff0c;我是哪吒。 一、前言 微服务已经是Java开发的必备技能&#xff…...

解决Mac电脑音乐显示歌名的乱码问题

最近想听「万能青年旅店」的歌&#xff0c;结果在Mac电脑的「音乐」里面打开后是乱码。 【原因】(求助于chatGPT) 乱码问题可能是由于MP3文件的元数据&#xff08;比如歌曲名、艺术家、专辑等信息&#xff09;的编码问题导致的。如果这些信息是用非标准的或者不兼容的字符编码…...

赢在电商设计!2024年最新电商设计实战技巧盘点

双十一、双十二、黑五的电商大促即将轮番将至&#xff0c;电商运营人迎来大忙季&#xff0c;选品、直播、采购入库、售后……各种环节都是影响电商转化的关键因素&#xff0c;而电商设计作为打通这些环节&#xff0c;打造高转化率电商平台的关键要素&#xff0c;能够吸引用户注…...

约数之和 (普通快速幂求逆元做法)

假设现在有两个自然数 A 和 B&#xff0c;S 是 AB 的所有约数之和。 请你求出 Smod9901 的值是多少。 输入格式 在一行中输入用空格隔开的两个整数 A 和 B 。 输出格式 输出一个整数&#xff0c;代表 Smod9901 的值。 数据范围 0≤A,B≤5107 输入样例&#xff1a; …...

每日一题(LeetCode)----二分查找(三)

每日一题(LeetCode)----二分查找&#xff08;三&#xff09; 1.题目&#xff08;69. x 的平方根 &#xff09; 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 **注意…...

使用 TensorFlow FasterRCNN 网络进行目标检测

目录 描述 此示例的工作原理 处理输入图形 数据准备 sampleUffFasterRCNN 插件 验证输出 TensorRT API 层和操作 TensorRT API 层和操作 先决条件 运行示例 示例 --help 选项 附加资源 许可 变更记录 已知问题 本示例&#xff0c;sampleUffFasterRCNN&#xff0…...

数据结构——顺序表(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…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...