浅谈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 value
    const value = refObj.current

    // updating the referenced object’s value
   refObj.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 value
   const textValue = elementRef.current.value


   // update the input element value
   elementRef.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 functions
 return (
       {//.. 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 钩子。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【NLP】训练chatglm2的评价指标BLEU,ROUGE

当进行一定程度的微调后&#xff0c;要评价模型输出的语句的准确性。由于衡量的对象是一个个的自然语言文本&#xff0c;所以通常会选择自然语言处理领域的相关评价指标。这些指标原先都是用来度量机器翻译结果质量的&#xff0c;并且被证明可以很好的反映待评测语句的准确性&a…

[回馈]ASP.NET Core MVC开发实战之商城系统(五)

经过一段时间的准备&#xff0c;新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始&#xff0c;在之前的文章中&#xff0c;讲解了商城系统的整体功能设计&#xff0c;页面布局设计&#xff0c;环境搭建&#xff0c;系统配置&#xff0c;及首页【商品类型&#xff0c;ba…

Vue2 第十八节 插槽

1.默认插槽 2.具名插槽 3.作用域插槽 插槽 ① 作用&#xff1a;让父组件可以向子组件指定位置插入html结构&#xff0c;也是一种组件间通信的方式&#xff0c;适用于父组件和子组件间通信 ② 分类&#xff1a;默认插槽&#xff0c;具名插槽&#xff0c;作用域插槽 一.默认…

【黑马头条之redis实现延迟任务】

本笔记内容为黑马头条项目的延迟任务精准发布文章部分 目录 一、实现思路 二、延迟任务服务实现 1、搭建heima-leadnews-schedule模块 2、数据库准备 3、安装redis 4、项目集成redis 5、添加任务 6、取消任务 7、消费任务 8、未来数据定时刷新 1.reids key值匹配 …

【有趣的设计模式】23 种设计模式详解和场景分析

前言 七大设计原则 1、单一原则&#xff1a;一个类只负责一个职责 2、开闭原则&#xff1a;对修改关闭&#xff0c;对扩展开放 3、里氏替换原则&#xff1a;不要破坏继承关系 4、接口隔离原则&#xff1a;暴露最小接口&#xff0c;避免接口过于臃肿 5、依赖倒置原则&#xff1…

黑客学习笔记(网络安全)

一、首先&#xff0c;什么是黑客&#xff1f; 黑客泛指IT技术主攻渗透窃取攻击技术的电脑高手&#xff0c;现阶段黑客所需要掌握的远远不止这些。 以前是完全涉及黑灰产业的反派角色&#xff0c;现在大体指精通各种网络技术的程序人员 二、为什么要学习黑客技术&#xff1f;…

怎么把图片变成表格?几个步骤轻松转换

如果您需要将一张图片中的数据转换成表格&#xff0c;这里有几个简单的步骤&#xff0c;可以帮助您完成这个转换过程。以下是需要注意的事项。 首先&#xff0c;我们先了解OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术。然后合理运用…

真的不想知道如何进行语音翻译才简单吗

郑希&#xff1a;嘿&#xff0c;王浩&#xff01;我听说你最近去了日本旅游&#xff0c;怎么样&#xff1f;体验如何&#xff1f; 王浩&#xff1a;哈哈&#xff0c;太棒了&#xff01;日本真是一个充满魅力的国家。不过&#xff0c;要说令我惊喜的还是语音翻译技术&#xff0…

论文阅读 - Social bot detection in the age of ChatGPT: Challenges and opportunities

论文链接&#xff1a;https://www.researchgate.net/publication/371661341_Social_bot_detection_in_the_age_of_ChatGPT_Challenges_and_opportunities 目录 摘要&#xff1a; 引言 1.1. Background on social bots and their role in society 1.2. The rise of AI-gene…

深度学习各层负责什么内容?

1、深度学习——神经网络简介 深度学习(Deep Learning)(也称为深度结构学习【Deep Structured Learning】、层次学习【Hierarchical Learning】或者是深度机器学习【Deep Machine Learning】)是一类算法集合&#xff0c;是机器学习的一个分支。 深度学习方法近年来&#xff0c…

微信小程序使用 canvas 2d 实现签字板组件

本文是在微信小程序中使用 canvas 2d 来实现签字板功能&#xff1b; 效果图&#xff1a; 代码&#xff1a; 1、wxml <view><canvas id"canvas"type"2d"bindtouchstart"start"bindtouchmove"move"bindtouchend"end&qu…

一文带你了解TCP/IP模型以及封装和分用

文章目录 1. 网络协议2. OSI七层网络模型3.TCP/IP (五层/四层)4. 封装和分用 1. 网络协议 网络协议是计算机网络中用于规定数据在网络中传输和处理的规则&#xff0c;它定义了在网络中通信的格式、规范和顺序。网络协议可以分为不同的层次&#xff0c;每个层次负责不同的功能和…

linux大神Brendan Gregg 性能之巅 第二版(systems performance)阅读心得(第一章)

笔者从事某副省级市政务云系统运维7年&#xff0c;最近被下面这张图吸引开始阅读Brendan Gregg的《性能之巅 第二版》&#xff0c;下面将结合自己的运维经验一起来看看这本700多页的书。 1、绪论 1.1 系统性能 系统性能的影响因素涉及软件和硬件&#xff0c;CPU、内存、磁盘io…

opencv 30 -图像平滑处理01-均值滤波 cv2.blur()

什么是图像平滑处理? 图像平滑处理&#xff08;Image Smoothing&#xff09;是一种图像处理技术&#xff0c;旨在减少图像中的噪声、去除细节并平滑图像的过渡部分。这种处理常用于预处理图像&#xff0c;以便在后续图像处理任务中获得更好的结果。 常用的图像平滑处理方法包括…

Redis的订阅者和发布者模式、主从双备和密码认证

四、Redis的订阅者和发布者模式、主从双备和密码认证 1、Redis的订阅者和发布者模式 两个数据库&#xff0c;一个是10&#xff0c;一个是15。订阅频道&#xff1a; 向频道推数据&#xff1a; 接收到数据&#xff1a; 2、redis的高可用&#xff08;HA&#xff09;主从双备 模拟…

idea application.yml配置文件没有提示或读不到配置

1.首先确定你的resources文件夹正常且yml文件图表和下面一样 不一样的右键去设置 2.确保你已经缩进了且层级关系正常 3.如果以上都不是&#xff0c;先考虑删除.idea重开试试 4.以上解决不了就装以下两个插件解决

vue - 【完整源码】实现评论区发表评论、回复评论、评论盖楼等功能,前端PC网站/移动端H5实现多用户评论与回复功能(详细示例源码,一键复制开箱即用)

效果图 在vue项目开发中,实现一个类似社交软件的评论区发表留言及回复等评论功能效果,可以无限回复盖楼。 一、功

Hololens2二维码识别

配置 目前大部分Hololens进行二维码识别的开发都是基于ZXing的包完成&#xff0c;首先需要完成zxing.unity.dll&#xff0c;很多地方应该都能下载&#xff0c;也可以直接上github上下载&#xff08;下载点这里&#xff09;。 下载时注意一下版本就好&#xff0c;过老的zxing兼…

Leetcode-每日一题【剑指 Offer 39. 数组中出现次数超过一半的数字】

题目 数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]输出: 2 限制&#xff1a; 1 < 数组长度 < 50000 解题思路 前置知…

无人机电力巡检方案在电网安全与维护中的应用

目前&#xff0c;无人机技术已经在各行各业都有广泛的应用&#xff0c;其中之一就是在电力巡检中的应用。无人机电力巡检方案以其高效、安全、精准的特点&#xff0c;为电网安全与维护带来了重大突破和进步。 一、无人机电力巡检方案是高效巡检的利器 传统的电力巡检方式需要人…