react读源码系列之初步了解ref
Opened this issue · 0 comments
wangzhenggui commented
前言
在react典型的数据流中,props传递是父子组件交互的唯一方式;在react典型的数据量之外,某些情况下(例如和第三方的dom库整合,或者某个dom元素focus等)为了修改子组件我们可能需要另一种方式,这就是ref方式。
初步认识ref
在react代码中我们可以通过3种方式来创建ref;
1、string ref
2、function
3、createRef(官方推荐)
通过代码来看下上面3种实现方式
首先看下string ref的方式创建
<div ref="div" /> // 这里我们直接定义一个string类型的ref属性
然后在使用的时候,可以直接通过this.refs.div的方式来获取实例,其实就是dom元素节点。
在看下function的方式是如何创建的
<div ref={instance => this.divRef = instance}></div> // 这里我们的ref是一个函数的形式
然后使用的时候,可以直接通过this.divRef的方式来获取实例,这个地方的实例也是dom节点,当然ref也是可以作用于组件上面的,只不过这里举例用的是dom节点而已
最后看下官方推介的使用方式
constructor() {
super()
this.objRef = React.createRef()
// {current: null} 初始化的objRef的数据结构
}
<div ref={this.objRef}></div> // 这里将ref绑定到this.objRef上
这里我们要得到实例,可以通过this.objRef.current获取到,然后对实例节点进行操作。
添加项
1、高阶组件中如何获取到低阶组件中的ref
高阶组件在props中定义一个钩子函数
setRefs = (instance) => {
this.productsRef = instance
}
<WrappedComponent
getRefs={instance => this.setRefs(instance)}
/>
低阶组件中定一个函数,当组件挂载的时候就会执行这个方法,然后回将当前节点对象作为参数传递到定的函数中,在去执行高阶组件的钩子函数,从而使高阶组件能够得到低阶组件中的ref
refcb = (instance) => {
this.props.getRefs(instance)
}
<div ref={this.refcb}></div>
2、函数式组件如何能够使用ref
这里我们通过使用React.forwardRef就可以能够得到组件的ref属性
const TargetComponent = React.forwardRef((props, ref) => {
return <div ref={ref}></div>
}) // 无状态组件,这里其实是通过函数的方式定义的组件
constructor() {
super()
this.targetRef = React.createRef() // 定义 ref
// {current: null}
}
<TargetComponent ref={this.targetRef}/>
其实这个地方也可以解决上面高阶组件获取ref的问题,只要在低阶组件中使用 React.forwardRef进行节点绑定就可以了。