• 浅谈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 值来更改引用对象的值。

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

    1. import { useRef } from ‘react’
    2. const myComponent = () => {
    3.     const refObj = useRef(initialValue)
    4.     return (
    5.     //
    6.     )
    7. }

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

    1. // inside a function
    2. const handleRefUpdate = () => {
    3.     // accessing the referenced object’s value
    4.     const value = refObj.current
    5.     // updating the referenced object’s value
    6.    refObj.current = newValue
    7. }

    您应该注意:

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

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

    使用 ref 访问 DOM 元素

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

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

    1. import {useRef} from ‘react’
    2. const myComponent = () => {
    3.     const elementRef = useRef()
    4.     return (
    5.         <input ref={elementRef} type=”text” />
    6.     )
    7. }

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

    1. const handleInput = () => {
    2.     //accessing the input element value
    3.    const textValue = elementRef.current.value
    4.    // update the input element value
    5.    elementRef.current.value = “Hello World”
    6. }

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

    Ref和useRef之间的区别

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

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

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

    1. import React, { useEffect} from 'react'
    2.  
    3. export default function useClickAway(refany, callback: Function) {
    4.    useEffect(() => {
    5.      function handleClickAway(event: any) {
    6.        if (ref.current && !ref.current.contains(event.target)) {
    7.          callback();
    8.        }
    9.      }
    10.  document.addEventListener("mousedown", handleClickAway);
    11.      return () => {
    12.        document.removeEventListener("mousedown", handleClickAway);
    13.      };
    14.    }, [ref]);
    15.  };

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

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

    1. import React, { useRef } from "react";
    2. //.. Other importations
    3. export default function Storefront() {
    4.   const targetElement = useRef(null)
    5.   const alertClickAway = () => {
    6.    alert("Clicked outside product 1")
    7.  }
    8.  useClickAway(targetElement, alertClickAway)
    9.  //.. Other functions
    10.  return (
    11.        {//.. Other parts of the application}
    12.        <div className="gallery">
    13.          <div className="col" ref={targetElement}>
    14.            <img src="https://i.postimg.cc/G207QNV7/image.png" alt="Product 1" />
    15.            <p>iWatch Series 6</p>
    16.            <div className="btns">
    17.              <button>
    18.                <img src="https://api.iconify.design/flat-color-icons:like.svg?color=%23888888" alt="like" />
    19.              </button>
    20.              <button>
    21.                <img 
    22.                   src="https://api.iconify.design/icon-park:buy.svg?color=%23888888"
    23.                   alt="add" />
    24.             </button>
    25.            </div>
    26.          </div>
    27.  )
    28. }

    在上面的代码片段中,我们有一个店面组件,我们在其中导入了自定义钩子,然后我们创建了一个新的引用对象 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 元素不同,功能组件没有实例。例如:

    1. import {useRef} from ‘react’
    2. const FunctionalComponent = () => {
    3.     return (
    4.         <h1>Hello World<>
    5. )
    6. }
    7. const myComponent = () => {
    8.          const elementRef = useRef()
    9.     return (
    10.         <FunctionalComponent ref={elementRef} />
    11.     )
    12. }

    由于组件 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 钩子。

  • 相关阅读:
    利器 | TestNG 与 Junit 对比,测试框架如何选择?
    Apollo7.0系统概述
    常见6种易被忽略的软件隐藏缺陷
    一文搞懂基于透视变换的车道线拟合
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java晋中学院教室管理系统83hw6
    OpenCV——级联分类器的样本训练记录
    Java对象的深度拷贝
    Educational Codeforces Round 134 (Rated for Div. 2) A~D
    C#小白(基础篇)1 (变量、赋值运算符、常量、+号的作用、占位符的使用)
    idea新建一个module时,文件夹显示灰色/pom.xml文件显示灰色且中间有条横线
  • 原文地址:https://blog.csdn.net/pantouyuchiyu/article/details/132067506