关于react中refs的使用

大刀
• 阅读 6072

在react中,可以使用refs来访问dom,或者在render中创建react对象。

使用refs的主要用途是

  1. 做一些动画的交互
  2. 媒体控件的播放
  3. 获取焦点、获取文本等
使用refs的方式有两种,一种是使用React.createRef() API,另一种是使用 回调形式的refs

先来介绍第一种方式,使用React.createRef() API


import React, { Component } from 'react'
export default class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // 直接使用原生 API 使 text 输入框获得焦点
    // 注意:我们通过 "current" 来访问 DOM 节点
    this.textInput.current.focus();
    console.log(this.textInput.current);//这边输出input的dom对象
  }

  render() {
    // 告诉 React 我们想把 <input> ref 关联到
    // 构造器里创建的 `textInput` 上
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />

        <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
   }
 }
第二种是回调 Refs,React 将在组件挂载时,会调用 ref 回调函数并传入 DOM 元素,当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 refs 一定是最新的。
import React, { Component } from 'react'
export default class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.textInput = null;
    this.setTextInputRef = element => {
      this.textInput = element;
    };
    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      if (this.textInput) this.textInput.focus();
    };
  }

  componentDidMount() {
    // 组件挂载后,让文本框自动获得焦点
    this.focusTextInput();
  }

  render() {
    // 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
    // 实例上(比如 this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef}
        />
        <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
后面来讲下,父子组件怎么样传递refs,你可以在组件间传递回调形式的 refs,代码如下
import React, { Component } from 'react'
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.inputElement = null;
    this.setTextInputRef = element => {
      this.inputElement = element;
    };
    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      console.log(this.inputElement)
      if (this.inputElement) this.inputElement.focus();
    };
  }
  componentDidMount() {
    // 组件挂载后,让文本框自动获得焦点
    this.focusTextInput();
  }
  render() {
    return (
      <div> 
      <CustomTextInput
        inputRef={el => this.inputElement = el}
      />
      <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
在上面的例子中,App 把它的 refs 回调函数当作 inputRef props 传递给了 CustomTextInput,而且 CustomTextInput 把相同的函数作为特殊的 ref 属性传递给了 <input>。结果是,在 App 中的 this.inputElement 会被设置为与 CustomTextInput 中的 input 元素相对应的 DOM 节点。
使用 React.forwardRef 来获取传递 ref,React 传递 ref 给 fowardRef 内函数 (props, ref) => ...,作为其第二个参数,然后转发到它渲染的 DOM
import React, { Component } from 'react'
const CustomTextInput = React.forwardRef((props, ref) => (
  <div>
      <input ref={ref} />
   </div>
));

class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.inputElement = React.createRef();
    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      console.log(this.inputElement)
      this.inputElement.current.focus();
    };
  }

  render() {
    return (
      <div> 
      <CustomTextInput
        ref={this.inputElement}
      />
      <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
点赞
收藏
评论区
推荐文章
晴空闲云 晴空闲云
3年前
vue3中基于script setup语法糖的$refs使用
在用vue3开发项目的时候,需要调用子组件的方法,于是想着用$refs来实现,但是我是使用scriptsetup语法糖,原先vue2的语法已经不适用了。于是一番折腾和查阅资料,终于搞定。vue2语法vue2语法在组件上设置ref属性后,在代码里可以通过this.$refs.ref值访问到对应的子组件。一个设置ref值的组件:html在js代码中可以通
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Karen110 Karen110
4年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
03. react 初次见面
    与浏览器的DOM元素不同,React当中的元素事实上是普通的对象,ReactDOM可以确保浏览器DOM的数据内容与React元素保持一致。1、将元素渲染到DOM中    首先我们在一个HTML页面中添加一个id"root" 的<div:<divid"root"
Stella981 Stella981
3年前
CodeMirror的使用方法
这里是利用vue来开发项目:1、利用textare生成编辑器<textarearef"textarea"</textarea2、创建编辑器对象leteditJsonCodeMirror.fromTextArea(this.$refs.textarea,{mode
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
React.js 时间组件 + 组件生命周期(更新模拟)
React是用于构建用户界面的JavaScript库,React组件使用一个名为render()的方法,接收数据作为输入,输出页面中对应展示的内容。React除了可以使用外部传入的数据以外(通过this.props访问传入数据),组件还可以拥有其内部的状态数据(通过this.state访问状态数据)。当组件的状态
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究