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 相关文章推荐
用JavaScript将从数据库中读取出来的日期型格式化为想要的类型。
Aug 15 Javascript
Mootools 1.2教程 设置和获取样式表属性
Sep 15 Javascript
jquery简单实现网页层的展开与收缩效果
Aug 07 Javascript
JS清除文本框内容离开在恢复及鼠标离开文本框时触发js的方法
Jan 12 Javascript
JavaScript Math 对象常用方法总结
Apr 28 Javascript
微信小程序 SocketIO 实例讲解
Oct 13 Javascript
jQuery动态创建元素以及追加节点的实现方法
Oct 20 Javascript
简单实现vue验证码60秒倒计时功能
Oct 11 Javascript
web前端vue filter 过滤器
Jan 12 Javascript
vue+element实现打印页面功能
May 20 Javascript
JS浮点数运算结果不精确的Bug解决
Aug 01 Javascript
JavaScript实现打砖块游戏
Feb 25 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的urlencode()URL编码函数浅析
2011/08/09 PHP
php将日期格式转换成xx天前的格式
2015/04/16 PHP
PHP读取CSV大文件导入数据库的实例
2017/07/24 PHP
详解Laravel5.6 Passport实现Api接口认证
2018/07/27 PHP
JavaScript创建命名空间(namespace)的最简实现
2007/12/11 Javascript
基于jquery的获取mouse坐标插件的实现代码
2010/04/01 Javascript
JavaScript 继承使用分析
2011/05/12 Javascript
js获取系统的根路径实现介绍
2013/09/08 Javascript
jquery选择器-根据多个属性选择示例代码
2013/10/21 Javascript
js实现交换运动效果的方法
2015/04/10 Javascript
angular.js分页代码的实例
2016/07/27 Javascript
Vue计算属性的学习笔记
2017/03/22 Javascript
Vue.js手风琴菜单组件开发实例
2017/05/16 Javascript
angular中不同的组件间传值与通信的方法
2017/11/04 Javascript
express如何使用session与cookie的方法
2018/01/30 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
2019/03/04 Javascript
微信小程序实现禁止分享代码实例
2019/10/19 Javascript
ZK中使用JS读取客户端txt文件内容问题
2019/11/07 Javascript
Js逆向实现滑动验证码图片还原的示例代码
2020/03/10 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
Python检测字符串中是否包含某字符集合中的字符
2015/05/21 Python
Python与Java间Socket通信实例代码
2017/03/06 Python
Django之提交表单与前后端交互的方法
2019/07/19 Python
python飞机大战 pygame游戏创建快速入门详解
2019/12/17 Python
pytorch实现CNN卷积神经网络
2020/02/19 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
Windows下Sqlmap环境安装教程详解
2020/08/04 Python
Html5实现单张、多张图片上传功能
2019/04/28 HTML / CSS
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
菲律宾酒店预订网站:Hotels.com菲律宾
2017/07/12 全球购物
味多美官网:蛋糕订购,100%使用天然奶油
2017/11/10 全球购物
2014年人力资源部工作总结
2014/11/19 职场文书
2015年清明节演讲稿范文
2015/03/17 职场文书
2015年小学数学教师工作总结
2015/05/20 职场文书
普希金的诗歌赏析(3首)
2019/08/20 职场文书
oracle重置序列从0开始递增1
2022/02/28 Oracle