• React 通过ref获取DOM对象或者子组件实例的用法


    在class组件中我们会用render返回一系列的组件或者DOM节点,有时我们需要获取某一个DOM节点或者子组件的实例,然后去对他进行一些手动的操作,我们可以在componentDidMount生命周期函数内通过DOM选择器来获取对应的DOM对象,但是这不是很方便,因为很多需要都需要我们保存对应的DOM对象的引用,管理起来也有点麻烦。

    我们可以用ref来获取某个子节点的实例,然后通过当前class组件实例的一些特定属性来直接获取子节点实例。(vue里也有一个ref属性,通过this.$refs来获取DOM实例,两个差不多的)

    ref有三种实现方法:

    • 字符串格式       ;字符串格式,这是React16版本之前用得最多的。         ;例如:<p ref="info">span</p>
    • 函数格式       ;ref对应一个方法,该方法有一个参数,也就是对应的节点实例   ;例如:<p ref={ele => this.info = ele}></p>
    • createRef方法     ;React16提供的一个API,使用React.createRef()来实现         

    方法一 字符串格式

    我们可以在render函数内返回的jsx代码片段中,给某个DOM节点或者子组件设置一个ref属性,传递一个字符串,这样当当前组件渲染完成后,我们可以通过当前class组件实例上的refs属性获取对应的一个DOM对象或者子组件实例

    比如jsx中有这样的一个代码片段:<p ref="info">span</p>,之后我们就可以通过this.refs.info获取到该p元素渲染后生成的DOM实例了。

    举个例子:

    <div id="root"></div>    
    <script type="text/babel">            
      class RefDemo extends React.Component{
        state = {no:1}
        componentDidMount = ()=>{ this.refs.info.textContent = "no = "+this.state.no }      //组件挂载完成后设置this.ref.info这个DOM节点的textContext
    
        test=()=>{ this.refs.info.textContent= "no = "+ ++this.state.no }                   //点击测试按钮后也修改this.ref.info这个DOM节点的textContext
        
        render(){
          return (
            <div>
              <button onClick={this.test}>测试</button>
              <p ref="info"></p>
            </div>
          )
        }
      }
      ReactDOM.render(<RefDemo></RefDemo>,root)
    </script>

    效果如下:

     writer by:大沙漠 QQ:22969969

    初始化时在componentDidMount生命周期函数内通过this.refs.info获取到p元素的节点,之后设置它的textContext属性,另外在测试按钮上也绑定了一个test属性,每次店家时递增this.state.no,并设置在this.refs.info这个DOM节点上,也就是p节点对象了。

    方法二 函数格式

    上面例子里符串格式的ref在内部会转换为一个函数格式,我们也可以直接将ref属性的值设置为一个函数,该函数可以传入一个参数,值是当前的DOM对象实例,比如:<p ref={ele => this.info = ele}></p>,这样我们在当前class组件内可以直接通过this.info获取到这个P元素的DOM对象实例了。

    我们改写一下上面的例子,用函数格式来写一下,如下:

    <div id="root"></div>    
    <script type="text/babel">            
      class RefDemo extends React.Component{
        state = {no:1}
        componentDidMount = ()=>{ this.info.textContent = "no = "+this.state.no }
    
        test=()=>{ this.info.textContent= "no = "+ ++this.state.no }
    
        render(){
          return (
            <div>
              <button onClick={this.test}>测试</button>
              <p ref={ele => this.info = ele}></p>                                  //这里以函数的形式来写,在其它逻辑内只需通过this.info就可以获取这个p节点实例了
            </div>
          )
        }
      }
      ReactDOM.render(<RefDemo></RefDemo>,root)
    </script>

    运行的效果和第一个例子是一样了,就不截图了。

    方法三 createRef方法

     createRef是React16新增的一个API,也是用于设置ref的,使用时,我们需要先执行

    React.createRef()

    执行后将返回一个{current: null}这样的对象,我们在jsx内将React.createRef()的返回值作为值设置在一个DOM节点的ref属性上,渲染后该DOM对象就会保存到React.createRef()返回的对象里的current属性上了。

    还是改写一下第一个例子,我们用createRef方法来写一下,如下:

    <div id="root"></div>    
    <script type="text/babel">            
      class RefDemo extends React.Component{
        state = {no:1}
        domp = React.createRef();                                                             //执行React.createRef()返回一个{current:null}对象
    
        componentDidMount = ()=>{ this.domp.current.textContent = "no = "+this.state.no }
    
        test=()=>{ this.domp.current.textContent= "no = "+ ++this.state.no }
    
        render(){
          return (
            <div>
              <button onClick={this.test}>测试</button>
              <p ref={this.domp}></p>                                                         //设置ref属性,值直接指向React.createRef()的返回值即可,也就是当前的domp属性,之后在其它地方可以直接使用this.domp.current获取这个P实例了
            </div>
          )
        }
      }
      ReactDOM.render(<RefDemo></RefDemo>,root)
    </script>

    运行的效果和第一个例子也是一样,这里也不贴截图了,如果把ref设置在一个子节点组件上,则获取的是组件实例。

    除了普通DOM节点或自组件的节点外,如果我们在jsx代码里引用了一个函数组件,由于在React当中函数组件也是返回jsx的,本身是没有实例的,因此我们设置ref属性获取到的值是为空的,此时可以用React.forwardRef()来解决,React.forwardRef也是用到了createRef()方法,具体的我们下篇文章再讲解。

  • 相关阅读:
    解决计算机改名无法连接TFS的问题
    MysqlHelper使用反射机制智能推算数据类型以及属性名称
    Cakephp中使用JavaScriptHelper来引入js文件
    CakePHP程序员必须知道的21条技巧
    cakephp文件结构
    去掉字符串前后所有空格
    小程序 支持html富文本吗
    2018年五月博客整理
    Angular cookies
    webstorm 快捷键
  • 原文地址:https://www.cnblogs.com/greatdesert/p/12697726.html
Copyright © 2020-2023  润新知