react中的refs属性的使用方法

        在React中,render执行的结果得到的并不是真正的DOM节点,结果仅仅是轻量级的JavaScript对象,我们称之为virtual DOM。

        虚拟DOM是React的一大亮点,具有batching(批处理)和高效的Diff算法。这让我们可以无需担心性能问题而”毫无顾忌”的随时“刷新”整个页面,由虚拟 DOM来确保只对界面上真正变化的部分进行实际的DOM操作。但是,有些场景需要获取某一个真实的DOM元素来交互,比如文本框的聚焦、触发强制动画等。所以怎么获取真实的dom元素呢?嗯、这就是今天的重点啦:refs

       React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。

那,具体怎么用,且看下面

1、为DOM元素添加Ref

ref属性接收一个回调函数,这个回调函数在组件挂载或者卸载的时候被调用。当ref用于一个HTML元素的时候,ref指定的回调函数在调用的时候会接收一个参数,该参数就是指定的DOM元素。

class Input extends Component {
    constructor(props){
        super(props);
       this.focus = this.focus.bind(this)
    }
    focus(){
        this.textInput.focus();
    }
    
    render(){
        return (
            <div>
                <input ref={(input) => { this.textInput = input }} />//input参数表示DOM本身
                <button  onClick={this.focus}>让input获取焦点</button>
            </div>
        )
    }
}

当我们在DOM Element中使用ref时,回调函数将接收当前的DOM元素作为参数,然后存储一个指向这个DOM元素的引用。那么在示例代码中,我们已经把input元素存储在了this.textInput中,在focus函数中直接使用原生DOM API实现focus聚焦。

2.为组件Component添加Ref
当ref属性用于一个class指定的自定义组件的时候,ref回调函数会接收到一个挂载的组件实例作为参数。

下面的例子展示了当CustomTextInput被挂载后马上模拟被点击:

class AutoFocusTextInput extends Component {
    componentDidMount(){
        this.textInput.focus();
    }
    
    render(){
        return (
            <Input ref={(input) => { this.textInput = input }}>
        )//ref回调函数会接收一个挂载的组件实例作为参数
    }
}
Input组件就是第一个实例的组件哦
当我们在<Input>中添加ref属性时,其回调函数接收已经挂载的组件实例<Input>作为参数,并通过this.textInput访问到其内部的focus方法。也就是说,上面的示例代码实现了当AutoFocusTextInput组件挂载后<Input>组件的自动聚焦。

注意:<Input>组件必须是使用class声明的组件

不能在无状态组件中使用`ref`。原因很简单,因为ref引用的是组件的实例,而无状态组件准确的说是个函数组件(Functional Component),没有实例。


3.为父组件暴露一个DOM的ref属性

这是Facebook非常不推荐的做法,因为这样会打破组件的封装性,这种方法只是某些特殊场景下的权宜之计。我们看看如何实现,上代码:

function CustomTextInput(props) {
  return (
    <div>
     //子级组件接收到父级组件传递过来的inputRef函数
     //当子级组件实例化的时候会将该input传入到该函数中,此时父级组件会
     //接收到子级组件的DOM结构(input元素)
      <input ref={props.inputRef} />
    </div>
  );
}
class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
      //为子级组件传入一个inputRef函数
        inputRef={el => this.inputElement = el}
      \/>
    );
  }
}

原理就是父组件把ref的回调函数当做inputRefprops传递给子组件,然后子组件<CustomTextInput>把这个函数和当前的DOM绑定,最终的结果是父组件<Parent>的this.inputElement存储的DOM是子组件<CustomTextInput>中的input。

官方推荐Ref常用情况

第一:管理焦点,文本选择,媒体播放(媒体回放)

第二:触发动画

第三:集成第三方的DOM库


结语:

`refs`提供的是另一种与react传统响应数据流完全不同的组件间交互方式,所以官方指出不要过度使用`refs`,而且从官方对它的态度来看,未来或许有更好的API来取代它。但目前来说`refs`仍是一个不错的解决方案。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值