React组件refs的使用详解


Posted in Javascript onFebruary 09, 2018

ref顾名思义我们知道,其实它就可以被看座是一个组件的参考,也可以说是一个标识。作为组件的属性,其属性值可以是一个字符串也可以是一个函数。

其实,ref的使用不是必须的。即使是在其适用的场景中也不是非用不可的,因为使用ref实现的功能同样可以转化成其他的方法来实现。但是,既然ref有其适用的场景,那也就是说ref自有其优势。关于这一点和ref的适用场景,官方文档中是这样说的:

在从 render 方法中返回 UI 结构之后,你可能想冲出 React 虚拟 DOM 的限制,在 render 返回的组件实例上调用某些方法。通常来说,这样做对于应用中的数据流动是不必要的,因为活跃的数据( Reactive data )流总是确保最新的 props 被传递到每一个从 render() 输出的子级中去。然而,仍然有几个场景使用这种方式是必须的,或者说是有益的:查找渲染出的组件的DOM标记(可以认为是DOM的标识ID),在一个大型的非React应用中使用React组件或者是将你现有的代码转化成React。

下面我们来看这样的一个场景(下面的例子经常被用于ref的讲解,可见下面描述的场景应该是比较经典的):通过某个事件使<input />元素的值被设为空字符串,然后使该<input />元素获得焦点。

var App = React.createClass({
  getInitialState: function() {
   return {userInput: ''};
  },
  handleChange: function(e) {
   this.setState({userInput: e.target.value});
  },
  clearAndFocusInput: function() {
   this.setState({userInput: ''}); // 设置值为空字符串
        //这里想要实现获得焦点   
  },
  render: function() {
   return (
    <div>
     <input
      value={this.state.userInput}
      onChange={this.handleChange}
     />
          <input type="button"
           value="Reset And Focus"
           onClick={this.clearAndFocusInput}
        />
    </div>
   );
  }
 });

在上面例子中,我们已经实现了点击按钮通知input元素将值设为空字符串,但是还没有实现使input元素获得焦点。这实现起来有些困难,因为在render()中返回的并不是实际的子组件的组合,仅仅是一个特定时间特定实例的描述。这句话感觉挺绕的,其实render返回的是虚拟的DOM,并不是真实的DOM。因此我们不需要仅仅着眼于那些从render()中返回的那些组件。

那说到这,对于我们如何实现获得焦点并没有太大的帮助。要想实现获得焦点这个功能我们需要借助ref来实现。上面我们提到过ref的值有两种类型,一种是字符串、一种是回调函数。

ref字符串上属性

React支持一个特殊的属性,你可以将这个属性加在任何通过render()返回的组件中。这也就是说对render()返回的组件进行一个标记,可以方便的定位的这个组件实例。这就是ref的作用。

ref的形式如下

<input ref="myInput" />

要想访问这个实例,可以通过this.refs来访问:

this.refs.myInput

先前版本中,我们可以通过React.findDOMNode(this.refs.myInput)来访问组件的DOM。但是现在,已经放弃了findDOMNode函数了,可以直接使用this.refs.myInput来进行访问。

ref回调函数

ref属性也可以是一个回调函数而不是一个名字。   这个函数将要在组件被挂载之后立即执行。这个参照的组件将会作为该函数的参数,这个函数可以立即使用这个组件参数,当然也可以将其保存供以后使用。

其形式也比较简单:

render: function() {
  return <TextInput ref={(c) => this._input = c} } />;
},
componentDidMount: function() {
  this._input.focus();
},

或者是

render: function() {
  return (
   <TextInput
    ref={function(input) {
     if (input != null) {
      input.focus();
     }
    }} />
  );
},

这里需要注意,当这个参照组件被卸载并且这个ref改变的时候,先前的ref的参数值将为null。这将有效的防止了内存的泄露。所以在上面代码中会有if判断:

if(input != null){
     input.focus();
}

上面介绍了ref的使用场景和方法,下面我们就将上面的例子来补充完整,从而实现获得焦点的功能

var App = React.createClass({
  getInitialState: function() {
    return {userInput: ''};
  },
  handleChange: function(e) {
    this.setState({userInput: e.target.value});
  },
  clearAndFocusInput: function() {
    this.setState({userInput: ''}); // Clear the input
    // We wish to focus the <input /> now!
    if (this.refs.myTextInput !== null) {
      this.refs.myTextInput.focus();
    }
  },
  render: function() {
    return (
      <div>
        <input
          value={this.state.userInput}
          onChange={this.handleChange}
          ref=”myTextInput”   
                     />
        <input
          type="button"
          value="Reset And Focus"
          onClick={this.clearAndFocusInput}
          />
      </div>
    );
  }
});
ReactDOM.render(
  <App />,
  document.getElementById('content')
);

在这个例子中, render 函数返回一个 <input /> 实例的描述。但是真正的实例通过 this.refs. myTextInput获取。只要 render 返回的某个子组件带有 ref="myTextInput" ,this.refs. myTextInput就会获取到正确的实例。

上面就是ref的所有内容,更多关于ref的介绍可以参考Ref to Components。

对于ref我们就介绍到这,希望本文对大家有所帮助。也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
使用jQuery管理选择结果
Jan 20 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
Jul 27 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
Nov 29 Javascript
jQuery 1.9.1源码分析系列(十三)之位置大小操作
Dec 02 Javascript
JavaScript实现拖拽元素对齐到网格(每次移动固定距离)
Nov 30 Javascript
bootstrap快速制作后台界面
Dec 05 Javascript
Vue.2.0.5实现Class 与 Style 绑定的实例
Jun 20 Javascript
详解基于vue的移动web app页面缓存解决方案
Aug 03 Javascript
使用vue-cli+webpack搭建vue开发环境的方法
Dec 22 Javascript
解决Mac下安装nmp的淘宝镜像失败问题
May 16 Javascript
Angular父子组件通过服务传参的示例方法
Oct 31 Javascript
js获取浏览器地址(获取第1个斜杠后的内容)
Sep 03 Javascript
详解vue-cli项目中的proxyTable跨域问题小结
Feb 09 #Javascript
使用express搭建一个简单的查询服务器的方法
Feb 09 #Javascript
js自定义trim函数实现删除两端空格功能
Feb 09 #Javascript
JavaScript运行原理分析
Feb 09 #Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
Feb 09 #Javascript
详解如何在项目中使用jest测试react native组件
Feb 09 #Javascript
vue checkbox 全选 数据的绑定及获取和计算方法
Feb 09 #Javascript
You might like
mysql_num_rows VS COUNT 效率问题分析
2011/04/23 PHP
解析将多维数组转换为支持curl提交的一维数组格式
2013/07/08 PHP
thinkPHP中钩子的使用方法实例分析
2017/11/16 PHP
在UpdatePanel内jquery easyui效果失效的解决方法
2010/04/11 Javascript
javascript中的float运算精度实例分析
2010/08/21 Javascript
JavaScript中的bold()方法使用详解
2015/06/08 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
基于jQuery实现发送短信验证码后的倒计时功能(无视页面关闭)
2016/09/02 Javascript
关于javascript事件响应的基础语法总结(必看篇)
2016/12/26 Javascript
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
页面缩放兼容性处理方法(zoom,Firefox火狐浏览器)
2017/08/29 Javascript
js中el表达式的使用和非空判断方法
2018/03/28 Javascript
详解webpack 入门与解析
2018/04/09 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
JavaScript数组去重的几种方法
2019/04/07 Javascript
简述pm2常用命令集合及配置文件说明
2019/05/30 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
2020/11/11 Javascript
vue 通过base64实现图片下载功能
2020/12/19 Vue.js
基于Python实现的百度贴吧网络爬虫实例
2015/04/17 Python
Python运算符重载用法实例
2015/05/28 Python
详解使用Python处理文件目录的相关方法
2015/10/16 Python
Python抓取手机号归属地信息示例代码
2016/11/28 Python
利用Python批量提取Win10锁屏壁纸实战教程
2018/03/27 Python
Python绘制频率分布直方图的示例
2019/07/08 Python
python数据化运营的重要意义
2019/11/25 Python
python 爬虫 实现增量去重和定时爬取实例
2020/02/28 Python
python如何求100以内的素数
2020/05/27 Python
编写html5时调试发现脚本php等网页js、css等失效
2013/12/31 HTML / CSS
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
介绍一下XMLHttpRequest对象
2012/02/12 面试题
材料化学应届生求职信
2013/10/09 职场文书
销售工作岗位职责
2013/12/24 职场文书
小摄影师教学反思
2014/04/27 职场文书
党员对照检查剖析材料
2014/10/13 职场文书
react 项目中引入图片的几种方式
2021/06/02 Javascript
解决Maven项目中 Invalid bound statement 无效的绑定问题
2021/06/15 Java/Android