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 相关文章推荐
指定js可访问其它域名的cookie的方法
Sep 18 Javascript
jquery 回车事件实现代码
Aug 23 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
May 08 Javascript
JavaScript中的setUTCDate()方法使用详解
Jun 11 Javascript
jquery拖动层效果插件用法实例分析(附demo源码)
Apr 28 Javascript
JS模拟实现ECMAScript5新增的数组方法
Mar 20 Javascript
微信小程序中使用javascript 回调函数
May 11 Javascript
vue教程之toast弹框全局调用示例详解
Aug 24 Javascript
bootstrap table方法之expandRow-collapseRow展开或关闭当前行数据
Aug 09 Javascript
vue使用keep-alive保持滚动条位置的实现方法
Apr 09 Javascript
vue+elementUI动态生成面包屑导航教程
Nov 04 Javascript
基于better-scroll 实现歌词联动功能的代码
May 07 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
不要轻信 PHP_SELF的安全问题
2009/09/05 PHP
PHP PDOStatement::fetchAll讲解
2019/01/31 PHP
ExtJS Window 最小化的一种方法
2009/11/18 Javascript
jQuery的DOM操作之删除节点示例
2014/01/03 Javascript
一款基于jQuery的图片场景标注提示弹窗特效
2015/01/05 Javascript
对JavaScript中this指针的新理解分享
2015/01/31 Javascript
浅谈JavaScript中的字符编码转换问题
2015/07/07 Javascript
js将table的每个td的内容自动赋值给其title属性的方法
2016/10/13 Javascript
js对字符串进行编码的方法总结(推荐)
2016/11/10 Javascript
bootstrap常用组件之头部导航实现代码
2017/04/20 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
2018/05/13 Javascript
微信小程序实现判断是分享到群还是个人功能示例
2019/05/03 Javascript
Python 正则表达式入门(中级篇)
2016/12/07 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
Django中的CBV和FBV示例介绍
2018/02/25 Python
python爬虫实例详解
2018/06/19 Python
Python告诉你木马程序的键盘记录原理
2019/02/02 Python
详解python播放音频的三种方法
2019/09/23 Python
Python图像处理库PIL的ImageGrab模块介绍详解
2020/02/26 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
Python监听剪切板实现方法代码实例
2020/11/11 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
CSS3圆角和渐变2种常用功能详解
2016/01/06 HTML / CSS
Hawes & Curtis澳大利亚官网:英国经典服饰品牌
2018/10/29 全球购物
Right-on官方网站:日本知名的休闲服装品牌
2019/07/12 全球购物
NOTINO英国:在线购买美容和香水
2020/02/25 全球购物
Wiggle澳大利亚:自行车、跑步、游泳商店
2020/11/07 全球购物
编写一子程序,将一链表倒序,即使链表表尾变表头,表头变表尾
2016/02/10 面试题
大二自我鉴定范文
2013/10/05 职场文书
农场厂长岗位职责
2013/12/28 职场文书
实验室的标语
2014/06/20 职场文书
电子商务专业求职信
2014/07/10 职场文书
英语三分钟演讲稿
2014/08/19 职场文书
暑期培训班策划方案
2014/08/26 职场文书
公务员上班玩游戏检讨书
2014/09/17 职场文书
债务追讨律师函
2015/06/24 职场文书