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

浅谈React中的ref和useRef

目录

什么是useRef?

使用 ref 访问 DOM 元素

Ref和useRef之间的区别

Ref和useRef的使用案例

善用工具

结论


在各种 JavaScript 库和框架中,React 因其开发人员友好性和支持性而得到认可。

大多数开发人员发现 React 非常舒适且可扩展,因为它提供了钩子。钩子是 React 附带的内置 API,允许开发人员与 React的状态和生命周期功能进行交互。钩子在类内部不起作用,因此它们只能在功能组件中使用。开发人员还可以决定创建自定义钩子。

React 比大多数 UI 库更能让你重新思考设计标准,允许开发人员自定义UI组件,例如使用 React 和 JSX 的抽象机制而不是典型的 DOM 规范创建视图。

在本文中,我们将讨论 React钩子函数 useRef ,使用 ref 访问 DOM 以及 ref 和 useRef 之间的区别。

什么是useRef?

React 中包含的各种钩子之一是 useRef 钩子;它用于引用功能组件中的对象,并在重新渲染之间保留引用对象的状态。

useRef 有一个名为“current”的属性,用于随时检索引用对象的值,同时还接受初始值作为参数。您可以通过更新 current 值来更改引用对象的值。

以下是创建引用对象的方法:

import { useRef } from ‘react’const myComponent = () => {const refObj = useRef(initialValue)return (//…)
}

在上面的代码片段中,我们有一个要在应用程序中引用的对象 refObj ,要访问值或更新值,我们可以像这样调用 current 该属性:

// inside a function
const handleRefUpdate = () => {// accessing the referenced object’s valueconst value = refObj.current// updating the referenced object’s valuerefObj.current = newValue
}

您应该注意:

  • 引用对象的值在重新渲染之间保持不变。

  • 更新引用对象的值不会触发重新呈现。

使用 ref 访问 DOM 元素

请记住,DOM 元素也是对象,我们可以使用useRef引用它们。但是现在,我们需要利用另一个名为 ref

ref 是一个 HTML 属性,它将引用的对象分配给 DOM 元素。让我们看看这是如何工作的:

import {useRef} from ‘react’const myComponent = () => {const elementRef = useRef()return (<input ref={elementRef} type=”text” />)
}

在上面的代码片段中,我们创建了一个新的引用对象,elementRef 并使用属性 ref 将其分配给输入标记。我们可以访问输入标签的值并像这样更新值:

const handleInput = () => {//accessing the input element valueconst textValue = elementRef.current.value// update the input element valueelementRef.current.value = “Hello World”
}

在上面的代码片段中,我们创建了一个函数,该函数获取输入元素的当前值并将其分配给 textValue。我们还将输入元素的值更新为“Hello World”。

Ref和useRef之间的区别

既然我们了解了useRefRef工作方式及它们的差异,让我们看看如何在实际应用程序中使用它们。例如,我们希望为弹出窗口实现一个点击离开事件侦听器。我们可以利用ref访问弹出窗口的 DOM 元素,并在弹出窗口外单击时进行侦听。

在你的react 应用中,你可以创建一个名为“hooks”的文件夹,这个文件夹将包含自定义钩子。

在文件夹中创建一个新文件 useClickAway ,并在文件中输入以下代码:

import React, { useEffect} from 'react'export default function useClickAway(ref: any, callback: Function) {useEffect(() => {function handleClickAway(event: any) {if (ref.current && !ref.current.contains(event.target)) {callback();}}document.addEventListener("mousedown", handleClickAway);return () => {document.removeEventListener("mousedown", handleClickAway);};}, [ref]);};

在上面的代码片段中,我们创建了一个接受引用对象作为 ref 和回调函数的自定义钩子,然后我们执行了一个事件侦听器来检查何时单击鼠标,如果单击不在当前 ref 上,则我们触发回调函数。

以下是产品页面上自定义挂钩的实现:

import React, { useRef } from "react";
//.. Other importations
export default function Storefront() {const targetElement = useRef(null)const alertClickAway = () => {alert("Clicked outside product 1")}useClickAway(targetElement, alertClickAway)//.. Other functionsreturn ({//.. Other parts of the application}<div className="gallery"><div className="col" ref={targetElement}><img src="https://i.postimg.cc/G207QNV7/image.png" alt="Product 1" /><p>iWatch Series 6</p><div className="btns"><button><img src="https://api.iconify.design/flat-color-icons:like.svg?color=%23888888" alt="like" /></button><button><img src="https://api.iconify.design/icon-park:buy.svg?color=%23888888"alt="add" /></button></div></div>)
}

在上面的代码片段中,我们有一个店面组件,我们在其中导入了自定义钩子,然后我们创建了一个新的引用对象 targetElement 并将其分配给产品库中的 div,然后我们创建了一个回调函数useClickAway,以便在使用ref在产品项外部单击鼠标时发出警报 targetElement 。

现在让我们看看输出:

图片

Ref和useRef的使用案例

你现在对什么是ref以及useRef,以及它们的使用有了一定的了解。refuseRef两者都很容易被滥用,会造成使用开销比较大。现在你可能需要考虑的是何时使用,以及如何尽可能避免使用。

以下是参考的一些用途:

  • 与输入元素交互:通过使用 refs 可以访问输入元素并执行焦点、更改跟踪或自动完成等功能。

  • 与第三方 UI 库交互:ref 可用于与第三方 UI 库创建的元素进行交互,这些元素使用标准 DOM 方法访问可能很棘手。例如,如果您使用第三方库生成滑块,则可以使用ref访问滑块的 DOM 元素,而无需被告知滑块库源代码的结构。

  • 媒体播放:您还可以使用 refs 访问图像、音频或视频等媒体资产,并与它们的呈现方式进行交互。例如,当元素进入视口时自动播放视频或延迟加载图像。

  • 复杂动画触发:传统上,CSS 关键帧或超时用于确定何时启动动画。在某些情况下(可能更复杂),您可以使用 refs 来观察 DOM 元素并确定何时开始动画。

在某些情况下(如下所示),不应使用引用:

  • 声明性案例:即使在使用 refs 的简单解决方案的情况下,也无需编写更昂贵的代码来执行相同的任务。例如,使用条件渲染来隐藏或显示 DOM 元素而不是 ref

  • 影响状态的元素:有时,使用refs的概念非常有趣,以至于您忽略了对元素所做的修改对应用程序生命周期的影响。您应该记住,对 ref 的更改不会导致重新渲染,并且ref在渲染中保持其对象的值。因此,建议避免在状态更改需要触发重新渲染的情况下使用 ref

  • 访问功能组件:不应被误认为功能组件的 DOM 元素可以使用Ref 属性进行引用。因为,与类组件或 DOM 元素不同,功能组件没有实例。例如:

import {useRef} from ‘react’const FunctionalComponent = () => {return (<h1>Hello World<>
)
}const myComponent = () => {const elementRef = useRef()return (<FunctionalComponent ref={elementRef} />)
}

由于组件 FunctionalComponent 没有实例,因此上述代码片段中的 ref 将不起作用。相反,我们可以将其转换为FunctionalComponent类组件或在 FunctionalComponent 组件的 forwardRef 中使用。

用工具

成功的前端工程师很会善用工具,这些年低代码概念开始流行,像国外的 Mendix,国内的 JNPF,这种新型的开发方式,图形化的拖拉拽配置界面,并兼容了自定义的组件、代码扩展,确实在 B 端后台管理类网站建设中很大程度上的提升了效率。

开源地址:JNPF体验中心

代码量少,系统的稳定性和易调整性都会得到一定的保障。基于代码生成器,可一站式开发多端使用 Web、Android、IOS、微信小程序。代码自动生成后可以下载本地,进行二次开发,有效提高整体开发效率。同时,支持多种云环境部署、本地部署给予最大的安全保障,可以快速搭建适合自身应用场景的产品。

结论

在本文中,我们讨论了如何使用 useRef 钩子创建引用,该钩子采用初始值并修改引用对象的“current”属性的值以更新其值。

我们看到了如何将“current”值与“ref”一起使用来访问 DOM 元素并与其属互。

我们将介绍如何创建一个接受引用 DOM 元素的自定义钩子和一个回调函数,以便在应用程序中使用 “ref” 和 “useRef” 来观察 DOM 元素上的单击事件。

此外,我们还讨论了“ref”和“useRef”的用例,何时使用它们,何时不使用它们。

在了解了ref 以及useRef 如何在不重新渲染父组件的情况下跟踪和更新可变值之后,您可以通过查看Refs 和 useRefs 的 React 的相关官方文档,来探索更多关于它们的信息或了解更多信息,甚至尝试其他 React 钩子。

相关文章:

浅谈React中的ref和useRef

目录 什么是useRef&#xff1f; 使用 ref 访问 DOM 元素 Ref和useRef之间的区别 Ref和useRef的使用案例 善用工具 结论 在各种 JavaScript 库和框架中&#xff0c;React 因其开发人员友好性和支持性而得到认可。 大多数开发人员发现 React 非常舒适且可扩展&#xff0c;…...

Linux C 获取主机网卡名及 IP 的几种方法

在进行 Linux 网络编程时&#xff0c;经常会需要获取本机 IP 地址&#xff0c;除了常规的读取配置文件外&#xff0c;本文罗列几种个人所知的编程常用方法&#xff0c;仅供参考&#xff0c;如有错误请指出。 方法一&#xff1a;使用 ioctl() 获取本地 IP 地址 Linux 下可以使用…...

解密外接显卡:笔记本能否接外置显卡?如何连接外接显卡?

伴随着电脑游戏和图形处理的需求不断增加&#xff0c;很多笔记本电脑使用者开始考虑是否能够通过外接显卡来提升性能。然而&#xff0c;外接显卡对于笔记本电脑是否可行&#xff0c;以及如何连接外接显卡&#xff0c;对于很多人来说仍然是一个迷。本文将为您揭秘外接显卡的奥秘…...

list与erase()

运行代码&#xff1a; //list与erase() #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;Item():name(" "),iid(0),value(0.0){}Item(string ss,int ii,double vv):name(ss),iid(ii),value(vv){}friend istr…...

Arcgis 分区统计majority参数统计问题

利用Arcgis 进行分区统计时&#xff0c;需要统计不同矢量区域中栅格数据的众数&#xff08;majority&#xff09;&#xff0c;出现无法统计majority参数问题解决 解决&#xff1a;利用copy raster工具&#xff0c;将原始栅格数据 64bit转为16bit...

vue2+wangEditor5富文本编辑器(图片视频自定义上传七牛云/服务器)

1、安装使用 安装 yarn add wangeditor/editor # 或者 npm install wangeditor/editor --save yarn add wangeditor/editor-for-vue # 或者 npm install wangeditor/editor-for-vue --save在main.js中引入样式 import wangeditor/editor/dist/css/style.css在使用编辑器的页…...

shell脚本练习--安全封堵脚本,使用firewalld实现

一.什么是安全封堵 安全封堵&#xff08;security hardening&#xff09;是指采取一系列措施来增强系统的安全性&#xff0c;防止潜在的攻击和漏洞利用。以下是一些常见的安全封堵措施&#xff1a; 更新和修补系统&#xff1a;定期更新操作系统和软件包以获取最新的安全补丁和修…...

双端冒泡排序

双端冒泡排序是对传统冒泡排序的改进&#xff0c;其主要改进在于同时从两端开始排序&#xff0c;相对于传统冒泡排序每次只从一端开始排序&#xff0c;这样可以减少排序的遍历次数。 传统冒泡排序从一端开始&#xff0c;每次将最大&#xff08;或最小&#xff09;的元素冒泡到…...

如何在Visual Studio Code中用Mocha对TypeScript进行测试

目录 使用TypeScript编写测试用例 在Visual Studio Code中使用调试器在线调试代码 首先&#xff0c;本文不是一篇介绍有关TypeScript、JavaScript或其它编程语言数据结构和算法的文章。如果你正在准备一场面试&#xff0c;或者学习某一个课程&#xff0c;互联网上可以找到许多…...

GO中Json的解析

一个json字串&#xff0c;想要拿到其中的数据&#xff0c;就需要解析出来 一、适用于json数据的结构已知的情况下 使用json.Unmarshal将json数据解析到结构体中 根据json字串数据的格式定义struct&#xff0c;用来保存解码后的值。这里首先定义了一个与要解析的数据结构一样的…...

chatgpt 提示词-关于数据科学的 75个词语

这里有 75 个 chatgpt 提示&#xff0c;可以立即将其用于数据科学或数据分析等。 1. 伪装成一个SQL终端 提示&#xff1a;假设您是示例数据库前的 SQL 终端。该数据库包含名为“用户”、“项目”、“订单”、“评级”的表。我将输入查询&#xff0c;您将用终端显示的内容进行…...

(自控原理)控制系统的数学模型

目录 一、时域数学模型 1、线性元件微分方程的建立 2、微分方程的求解方法​编辑 3、非线性微分方程的线性化 二、复域数学模型 1、传递函数的定义 2、传递函数的标准形式 3、系统的典型环节的传递函数 4、传递函数的性质 5、控制系统数学模型的建立 6、由传递函数求…...

Webpack5 cacheGroups

文章目录 一、 cacheGroups是什么&#xff1f;二、怎么使用cacheGroups&#xff1f;三、cacheGroups实际应用之一&#xff1f; 一、 cacheGroups是什么&#xff1f; 在Webpack 5中&#xff0c;cacheGroups是用于配置代码拆分的规则&#xff0c;它可以帮助你更细粒度地控制生成…...

前端面试的游览器部分(5)每篇10题

41.什么是浏览器的同步和异步加载脚本的区别&#xff1f;你更倾向于使用哪种方式&#xff0c;并解释原因。 浏览器的同步和异步加载脚本是两种不同的脚本加载方式&#xff0c;它们的主要区别在于加载脚本时是否阻塞页面的解析和渲染。 同步加载脚本&#xff1a; 同步加载脚本…...

数据挖掘七种常用的方法汇总

数据挖掘(Data Mining)就是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;提取隐含在其中的、人们事先不知道的、但又是潜在有用的信息和知识的过程。这个定义包括几层含义&#xff1a;数据源必须是真实的、大量的、含噪声的&#xff1b;发现的是用户…...

自然语言处理学习笔记(二)————语料库与开源工具

目录 1.语料库 2.语料库建设 &#xff08;1&#xff09;规范制定 &#xff08;2&#xff09;人员培训 &#xff08;3&#xff09;人工标注 3.中文处理中的常见语料库 &#xff08;1&#xff09;中文分词语料库 &#xff08;2&#xff09;词性标注语料库 &#xff08;3…...

Rust dyn - 动态分发 trait 对象

dyn - 动态分发 trait 对象 dyn是关键字&#xff0c;用于指示一个类型是动态分发&#xff08;dynamic dispatch&#xff09;&#xff0c;也就是说&#xff0c;它是通过trait object实现的。这意味着这个类型在编译期间不确定&#xff0c;只有在运行时才能确定。 practice tr…...

uniapp 中过滤获得数组中某个对象里id:1的数据

// 假设studentData是包含多个学生信息的数组 const studentData [{id: 1, name: 小明, age: 18},{id: 2, name: 小红, age: 20},{id: 3, name: 小刚, age: 19},{id: 4, name: 小李, age: 22}, ]; // 过滤获取id为1的学生信息 const result studentData.filter(item > ite…...

Django系列之Channels

1. Channels 介绍 Django 中的 HTTP 请求是建立在请求和响应的简单概念之上的。浏览器发出请求&#xff0c;Django服务调用相应的视图函数&#xff0c;并返回响应内容给浏览器渲染。但是没有办法做到 服务器主动推送消息给浏览器。 因此&#xff0c;WebSocket 就应运而生了。…...

HTTP——五、与HTTP协作的Web服务器

HTTP 一、用单台虚拟主机实现多个域名二、通信数据转发程序 &#xff1a;代理、网关、隧道1、代理2、网关3、隧道 三、保存资源的缓存1、缓存的有效期限2、客户端的缓存 一台 Web 服务器可搭建多个独立域名的 Web 网站&#xff0c;也可作为通信路径上的中转服务器提升传输效率。…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

python爬虫——气象数据爬取

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