上节课我们深入讨论了一下关于回调式refs被调用次数的问题,这节课我们来学洗另一个使用refs的方法,就是createRef

回顾

在开始学习createRef之前我们来对上节课的内容来做一个简单的回顾:

  • 回调式refs会在页面第一次被渲染时调用一次
  • 如果回调式refs是内联函数形式,那么在state更新之后,会被重新调用两次
  • 内联函数形式的回调式refs调用次数对程序不会有影响
  • 类组件绑定函数的方式可以解决refs被多次调用的问题

以上便是对上节课内容的回顾,那么今天继续学习refs的使用

createRef的使用

我们先来看一下我们的代码:

class Demo extends React.Component {
  myRef = React.createRef();
  render() {
    return(
      <div>
        <input ref={this.myRef} type="text" placeholder="click" />
        <button onClick={this.showData} type="button">Click</button>
      </div>
    );
  }
  showData = () => { console.log(this.myRef); };
}

我们好像看见了一个陌生的面孔,也是我们这节课的主角儿React.creatRef,这个是干什么的呢?其实只要调用了React.createRef那么就会得到一个容器,这个容器里面会收集所有被ref属性标识的DOM节点。

那看我们myRef = React.createRef();这一步是做了什么啊?是不是把我们调用React.createRef得到的容器放在组件实例对象自身上的myRef属性了啊?那么我们在标签里的ref属性就省心了。就直接ref={this.myRef}

那当react通过组件实例对象调用了render方法的时候发现这个input标签里面有个ref属相,而且这个属性还是React.createRef返回的一个容器,那么是不是就自动把当前的DOM节点传入到了这个容器中了?

那么好我们来看一下这个容器长什么样子。

image-20211223111503313

大家可以看见这是一个对象,里面有一个current属性,属性的值就是我们的input标签所在节点。

那么我们要想拿到这个节点里的value那么我们是不是要通过this.myRef.current.value?那么我们来看一下效果吧。

image-20211223111841310

输出结果正如我们所预期的一样。那我们就可以实现我们想要的功能了:

class Demo extends React.Component {
  myRef = React.createRef();
  render() {
    return(
      <div>
        <input ref={this.myRef} type="text" placeholder="click" />
        <button onClick={this.showData} type="button">Click</button>
      </div>
    );
  }
  showData = () => { alert(this.myRef.current.value); };
}

我们是不是想要弹窗提醒啊?那我们看一下效果呗

image-20211223112041484

我们的功能算是正常实现了。

那么有朋友要说了,那我们就都用createRef吧,所有东西都往这存还挺好用的。不行!因为React.createRef所返回的容器是“专人专用的”,也就是说这个容器只能存一个DOM节点。比如这样:

 class Demo extends React.Component {
   myRef = React.createRef();
   render() {
     return (
       <div>
         <input ref={this.myRef} type="text" placeholder="click" />
         <button ref={this.myRef} onClick={this.showData} type="button">Click</button>
       </div>
     );
   }
   showData = () => { console.log(this.myRef); };
 }

大家看,我给下面的button标签也加了ref={this.myRef},那么再来看一下效果

image-20211223112556860

这回里面依然只又一个属性,因为button标签中的ref是后加的,所以就会把之前input标签的节点给顶掉。所以说如果要有多个标签要添加ref并且要用React.createRef方法的话,那就得定义多个容器。那这样的话使用createRef是不是太繁琐了?可是这个却是react官方目前最推荐的一直形式。但是我们通常来说都不接受官方的推荐,我还是喜欢用回调的方式。

以上便是createRef的用法

总结

  • createRef可以返回一个容器用于存放被ref属性标识的DOM节点
  • createRef返回的容器“专人专用”
  • 如果多个标签要被标识,就要创建多个容器

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/use_createRef/