React中ref的四种使用方法

news2024/11/25 18:47:14

个人公众号

公众号文章-React中ref的四种使用方法
个人公众号,求关注公众号~ 求指导,求点赞,求评论。

写在前面的废话

什么时候使用ref的环境就不说了,比如我们要获取一个输入框的value,无法通过state去获取,这时候用ref就很合适。

本文的重点介绍的是ref的四种方法,因为现在使用的react版本是18.2,所以部分的方法都算是已经过时了,并有自己的局限性,所以如果方便,更推荐使用useRef的方式。

stringRef

在描述stringRef之前,先贴上一段官网中关于stringRef的描述。

如果你以前使用过 React,你可能熟悉一个较旧的 API,其中属性是一个字符串,比如 ,而 DOM 节点被访问为 .我们建议不要这样做,因为字符串引用存在一些问题,被认为是遗留的,并且可能会在将来的某个版本中删除。
在知道了字符串的ref问题之后,由于部分旧的代码我们还会使用到stringRef,我们还是得看看stringRef的使用。

import { PureComponent, ReactNode } from "react";class RefComponent extends PureComponent {
  handleClick = () => {
    const element: any = this.refs.stringRef;
    console.log(element?.value);
  };
  render(): ReactNode {
    return (
      <div>
        <input ref="stringRef" />
        <button
          onClick={() => {
            this.handleClick();
          }}
        >
          点击获取输入框的值
        </button>
      </div>
    );
  }
}export default RefComponent;

效果如下:
在这里插入图片描述

当点击了我们的按钮的时候,就直接获取到了输入框中的值。

而在控制台中也有这么一个警告

Warning: A string ref, “stringRef”, has been found within a strict
mode tree. String refs are a source of potential bugs and should be
avoided. We recommend using useRef() or createRef() instead.

Learn more about using refs safely here:
https://reactjs.org/link/strict-mode-string-ref

而这个警告也与官网的提示一样,讲述了stringRef是一个"deprecated"的API,建议我们使用useRef或者是createRef这两个API。
除此之外,在第五行的代码中,由于我们使用了this,而只有在类组件中,才存在了this,因此我们无法在函数组件中使用到stringRef。
综上所述,不建议再使用stringRef,除非你的项目很老,只能使用stringRef。

createRef

相对于stringRef,createRef算是比较正常点的,而因为stringRef有bug的原因,所以react也推荐在class组件使用createRef。

与直接使用stringRef不同,我们需要先在constructor中,使用createRef构建一个ref对象,再将其绑定到元素上去,这样子才可以去获取到元素。代码如下:

import React, { PureComponent, ReactNode, RefObject } from "react";class RefComponent extends PureComponent {
  inputRef: RefObject<HTMLInputElement> | undefined;
  constructor(props: {} | Readonly<{}>) {
    super(props);
    this.inputRef = React.createRef();
  }
  handleClick = () => {
    const element: any = this.inputRef;
    console.log(element?.current?.value);
  };
  render(): ReactNode {
    return (
      <div>
        <input ref={this.inputRef} />
        <button
          onClick={() => {
            this.handleClick();
          }}
        >
          点击获取输入框的值
        </button>
      </div>
    );
  }
}export default RefComponent;


需要注意的是,我们无法再直接使用ref.value的方式去获取到值,而是需要使用ref?.current?.value的方式获取到值。

而将createRef放置在constructor中的原因,是因为如果放在

componentDidMount的时候,很容易出现createRef未能完成初始化,会出现undefined,同时,也最好使用?.的形式,防止放在constructor的时候,也未能及时初始化的情况。
同样的,本代码也只能放在类组件中使用,无法放在函数组件中使用,因为没有this…
也需要注意一点,这儿我用的类型是RefObject,而部分同学喜欢用LegacyRef,后者泛指的是Ref类型,是兼容之前stringRef的版本。
效果如下:
在这里插入图片描述

CallbackRef

ref属性,除了可以接受ref对象之外,也可以接受函数,这就称之为CallbackRef,也没啥好讲的,代码如下

import React, { LegacyRef, PureComponent, ReactNode, RefObject } from "react";class RefComponent extends PureComponent {
  inputRef: HTMLElement | undefined | null;handleClick = () => {
    const element: any = this.inputRef;
    console.log(element?.value);
  };
  render(): ReactNode {
    return (
      <div>
        <input
          ref={(ref) => {
            this.inputRef = ref;
          }}
        />
        <button
          onClick={() => {
            this.handleClick();
          }}
        >
          点击获取输入框的值
        </button>
      </div>
    );
  }
}export default RefComponent;

需要注意的是,这次的inputRef并不是RefObject,而是一个html对象,所以我们只需要当他做一个html对象处理就好了。

唯一要注意的是,依旧需要在类组件中使用,无法在函数组件中使用,毕竟都是对ref的操作。

useRef

与前面的类组件中对ref对象的操作,函数组件在获得了hook之后,也出现了对应的useRef钩子与之对应。毕竟ref对象都是只能在类组件中使用,前三个方式,无论怎么说,本质都是在类组件中对ref属性做一些变种,而useRef在函数式编程为王道的今天,更加的需要了解。
useRef返回的是一个可变的ref对象,类型为refObject,所以依旧需要用到上面的current属性去读取我们要的值。
useRef需要我们先使用userRef,接着在ref属性上使用回调函数的方式绑定ref。代码如下:

import { useRef } from "react";function RefComponent() {
  const inputRef = useRef<HTMLElement | null>();
  const handleClick = () => {
    const element: any = inputRef;
    console.log(element?.current?.value);
  };
  return (
    <>
      <input
        ref={(ref) => {
          inputRef.current = ref;
        }}
      />
      <button
        onClick={() => {
          handleClick();
        }}
      >
        点击获取输入框的值
      </button>
    </>
  );
}
export default RefComponent;


效果如下:

在这里插入图片描述

最后的废话

大人,现在已经是2023年的年尾了,别想那么多了,用useRef吧…不要搞那么多事情了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

固态硬盘速度测试:硬盘实际性能是否符合标准?

在进行固态硬盘速度测试之前我们先来了解一下固态硬盘的读写速度是什么。固态硬盘的读写速度主要分为顺序读写和随机读写&#xff08;4K&#xff09;。 ​顺序读写&#xff1a;指的是硬盘在读写连贯、集中大文件时候的速度。比如在读取、拷贝单个视频文件时&#xff0c;就是硬盘…

Light-Head R-CNN: In Defense of Two-Stage Object Detector(2017.11)

文章目录 Abstract1. Introduction2. Related works3. Our Approach3.1. Light-Head R-CNN3.1.1. R-CNN subnet3.1.2. Thin feature maps for RoI warping 3.2. Light-Head R-CNN for Object Detection Conclusion 原文链接 Abstract 在本文中&#xff0c;我们首先研究了为什么…

如何能够获得想要的科研数据资料呢?

在当今的学术界&#xff0c;科研数据的获取对于研究人员来说至关重要。然而&#xff0c;由于各种原因&#xff0c;如数据难以获取、数据不完整或不准确等&#xff0c;使得许多研究人员面临困难。那么&#xff0c;如何才能够获得的科研数据资料呢&#xff1f; 一、参考文献 根…

实验报告-实验四(时序系统实验)

软件模拟电路图 说明 SW&#xff1a;开关&#xff0c;共六个Q1~Q3&#xff1a;输出Y0~Y3&#xff1a;输出 74LS194 首先&#xff0c;要给S1和S0高电位&#xff0c;将A~D的数据存入寄存器中&#xff08;如果开始没有存入数据&#xff0c;那么就是0000在里面移位&#xff0c;不…

Azure Machine Learning - 在 Azure 门户中创建演示应用

目录 准备环境启动向导配置搜索结果添加自动提示功能添加建议创建、下载和执行清理资源 使用 Azure 门户的“创建演示应用”向导来生成可下载的“localhost”样式的 Web 应用&#xff0c;该应用在浏览器中运行。 根据其配置&#xff0c;生成的应用在首次使用时就能正常运行&…

Spring Cloud Alibaba实践:使用Nacos实现服务注册与发现

什么是Nacos Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构 (例如…

初学者如何入门深度学习:以手写数字字符识别为例看AI 的学习路径,一图胜千言!超多高清大图收集整理

文章大纲 深度神经网络机器学习,深度学习,数据发掘之间的关系神经元与激活函数理解深度神经网络最好的可视化工具深度学习基础概念能解决神马种类的问题?卷积池化以手写字符识别为例讲述深度学习的分类问题MNIST 数据集简介初学者入门 :生成式 AI -- generative-ai-for-beg…

GPT-Crawler一键爬虫构建GPTs知识库

GPT-Crawler一键爬虫构建GPTs知识库 写在最前面安装node.js安装GPT-Crawler启动爬虫结合 OpenAI自定义 assistant自定义 GPTs&#xff08;笔者用的这个&#xff09; 总结 写在最前面 GPT-Crawler一键爬虫构建GPTs知识库 能够爬取网站数据&#xff0c;构建GPTs的知识库&#xf…

AWS Remote Control ( Wi-Fi ) on i.MX RT1060 EVK - 2 “架构 AWS”

接续上一章节&#xff0c;我们把开发环境架设好之后&#xff0c;此章节叙述如何建立 AWS IoT 环境&#xff0c;请务必已经有 AWS Account&#xff0c;申请 AWS Account 之流程将不在此说明。 III-1. 登入AWS IoT&#xff0c; 在“管理”>“所有装置”>“实物”下点击“建…

element-plus组件中的el-drawer的使用

在项目的制作过程中经常会用到弹窗组件&#xff0c;这里假设一种情况当你在一个页面需要多个弹窗组件的时候怎么样才能精准的打开和关闭对应的弹窗呐&#xff1f;&#xff1f; ① 绑定一个点击事件----【给点击事件传入一个下标】这里是打开事件 ② 使用element-plus中的 :befo…

最新关于openai.APIConnectionError: Connection error.的解决方法

其实是和以前一样的处理方式&#xff0c;&#xff08;挂魔法&#xff09;修改代理&#xff0c;但是openai的源码改了&#xff0c;好多博客的方法不能用了。现在给一个新的修改方式&#xff0c;自己用的&#xff0c;发现可以。 1.找到pip下载的openai的Lib&#xff0c;找到_base…

2023年度端侧transformer类分类力作SwiftFormer模型解读

写在前面&#xff1a;本篇直接结合代码来理解网络的笔记 paper: Swiftformer-paper code: https://github.com/Amshaker/SwiftFormer 文章目录 网络结构精析零、整体一、patch embed二、stage 网络结构精析 零、整体 可以看到结构中&#xff0c;整体就是&#xff1a; stem -&…

融云 Global IM UIKit,灵活易用的即时通讯组件设计思路和最佳实践

&#xff08;全网都在找的《社交泛娱乐出海作战地图》&#xff0c;点击获取&#x1f446;&#xff09; 融云近期推出的 Global IM UIKit&#xff0c;支持开发者高效满足海外用户交互体验需求&#xff0c;且保留了相当的产品张力赋予开发者更多自由和灵活性&#xff0c;是实现全…

算能技术资料地址、Demo github地址

技术资料地址&#xff1a; https://developer.sophgo.com/site/index/material/38/all.html Demo github地址&#xff1a;https://github.com/sophgo/sophon-demo

--enable-preview JDK预览新功能运行打包

--enable-preview JDK预览功能运行打包 1. 这里以JDK19的预览功能虚拟线程为例2. 解决方案&#xff1a;在pom文件中加入build 1. 这里以JDK19的预览功能虚拟线程为例 以下这段代码是无法运行的。会报错 SpringBootApplication public class SpringBootOkhttpApplication {pub…

【PID学习笔记 6 】控制系统的性能指标之二

写在前面 上文介绍了控制系统的稳态与动态、过渡过程、阶跃响应以及阶跃信号作用下过渡过程的四种形式。本文紧接上文&#xff0c;首先总结过渡过程的分类&#xff0c;然后介绍控制系统的性能评价&#xff0c;最后重点介绍控制系统性能指标中的单项指标。 一、过渡过程的分类…

【C】递归函数

一、什么是递归 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。 我们先了解一个知识&#xff1a; 每一次函数调用&#xff0c;都会向内存栈区上申请一块空间。 这块空间主要用来存放函数中的局部变量&#xff0c;和函数调用过程中…

圈子社交系统:打破时间与空间的限制。APP小程序H5三端源码交付,支持二开!

在现代社会&#xff0c;社交已成为人们生活中不可或缺的一部分。然而&#xff0c;传统的社交方式往往受制于时间和空间的限制&#xff0c;使得人们难以充分发挥社交的潜力。为了解决这一问题&#xff0c;圈子社交系统应运而生。 圈子社交系统通过技术手段打破时间与空间的限制&…

一文读懂MySQL基础知识文集

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

面试题:公司规定所有接口都用 post 请求,这是为什么?

文章目录 前言get 与 post 的区别所有接口都用 post 请求&#xff1f;网友程墨 Morgan网友苏莉安网友大宽宽 前言 最近在逛知乎的时候发现一个有趣的问题&#xff1a;公司规定所有接口都用 post 请求&#xff0c;这是为什么&#xff1f; 看到这个问题的时候其实我也挺有感触的…