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,使⽤ateRef()来实现     
⽅法⼀字符串格式
我们可以在render函数内返回的jsx代码⽚段中,给某个DOM节点或者⼦组件设置⼀个ref属性,传递⼀个字符串,这样当当前组件渲染完成后,我们可以通过当前class组件实例上的refs属性获取对应的⼀个DOM对象或者⼦组件实例
⽐如jsx中有这样的⼀个代码⽚段:<p ref="info">span</p>,之后我们就可以通过fs.info获取到该p元素渲染后⽣成的DOM实例了。
举个例⼦:
<div id="root"></div>
<script type="text/babel">
class RefDemo extends React.Component{
state = {no:1}
componentDidMount = ()=>{ Content = "no = "+ }      //组件挂载完成后设置f.info这个DOM节点的textContext
react router dom 6
test=()=>{ Content= "no = "+ ++ }                  //点击测试按钮后也修改f.info这个DOM节点的textContext
render(){
return (
<div>
<button onClick={st}>测试</button>
<p ref="info"></p>
</div>
)
}
}
</script>
效果如下:
初始化时在componentDidMount⽣命周期函数内通过fs.info获取到p元素的节点,之后设置它的textContext属性,另外在测试按钮上也绑定了⼀个test属性,每次店家时递增,并设置在fs.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 = ()=>{ Content = "no = "+ }
test=()=>{ Content= "no = "+ ++ }
render(){
return (
<div>
<button onClick={st}>测试</button>
<p ref={ele => this.info = ele}></p>                                  //这⾥以函数的形式来写,在其它逻辑内只需通过this.info就可以获取这个p节点实例了
</div>
)
}
}
</script>
运⾏的效果和第⼀个例⼦是⼀样了,就不截图了。
⽅法三 createRef⽅法
createRef是React16新增的⼀个API,也是⽤于设置ref的,使⽤时,我们需要先执⾏
执⾏后将返回⼀个{current: null}这样的对象,我们在jsx内将ateRef()的返回值作为值设置在⼀
个DOM节点的ref属性上,渲染后该DOM对象就会保存到ateRef()返回的对象⾥的current属性上了。
还是改写⼀下第⼀个例⼦,我们⽤createRef⽅法来写⼀下,如下:
<div id="root"></div>
<script type="text/babel">
class RefDemo extends React.Component{
state = {no:1}
domp = ateRef();                                                            //执⾏ateRef()返回⼀个{current:null}对象
componentDidMount = ()=>{ this.Content = "no = "+ }
test=()=>{ this.Content= "no = "+ ++ }
render(){
return (
<div>
<button onClick={st}>测试</button>
<p ref={this.domp}></p>                                                        //设置ref属性,值直接指向ateRef()的返回值即可,也就是当前的domp属性,之后在其它地⽅可以直接使⽤this.domp.current获取这个P实例了        </div>
)
}
}
</script>
运⾏的效果和第⼀个例⼦也是⼀样,这⾥也不贴截图了,如果把ref设置在⼀个⼦节点组件上,则获取的
是组件实例。
除了普通DOM节点或⾃组件的节点外,如果我们在jsx代码⾥引⽤了⼀个函数组件,由于在React当中函数组件也是返回jsx的,本⾝是没有实例的,因此我们设置ref属性获取到
的值是为空的,此时可以⽤React.forwardRef()来解决,React.forwardRef也是⽤到了createRef()⽅法,具体的我们下篇⽂章再讲解。