首先,我们来看一下这个函数的使用实例
const Son1 = React.forwardRef((props, ref) => {
return (
<div>
<p>this input is from Son1</p>
<input ref={ref} type='text' />
</div>
)
})
很明显,上图其实利用函数创造了一个组件,明显将props参数和ref参数区分开来,将ref参数赋值和Son1组件的input子元素进行绑定,明显是直接越过了 Son1,这就是其第一个作用:将ref的传值穿透组件直达内部元素,我们可以看以下两个让input聚焦的写法
传统写法
// 创建一个子组件
class Son extends React.Component {
constructor(props) {
super(props)
}
render () {
return (
<div>
<p>this input is from Son</p>
<input type="text" ref={this.props.inputRef} /> //3.inputRef传递给ref
</div>
)
}
}
class Father extends React.Component {
constructor(props) {
super(props)
this.inputRef = React.createRef()//1.创建
this.handleClick = this.handleClick.bind(this)
}
handleClick () {
this.inputRef.current.focus()
}
render () {
return (
<div>
<Son inputRef={this.inputRef} /> //2.赋值给inputRef
<p>this button is from Father</p>
<br />
<button onClick={this.handleClick()}>点击让input聚焦</button>
</div>
)
}
}
上图中ref的传递经过了三个步骤,接下来看一下新写法
const Son1 = React.forwardRef((props, ref) => {
return (
<div>
<p>this input is from Son1</p>
<input ref={ref} type='text' />
</div>
)
})
class Father extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
this.input = React.createRef() //1.创建
}
handleClick () {
// console.log(this.input.current);
this.input.current.focus()
}
render () {
return (
<div>
<Son1 ref={this.input} /> //2.ref直接穿透
<p>this button is from Father</p>
<br />
<button onClick={this.handleClick}>点击聚焦</button>
</div>
)
}
}
新写法明显只有两个层级,省了一步,也就是说forwardRef就是用来传递ref的,和createRef一样,就是省了一步。
第二种用法就是forwardRef在高阶组件中的使用,我觉得官网上的例子没写好,上代码
// 定义一个组件用作高阶组件的参数
class Input extends React.Component {
constructor(props) {
super(props)
}
render () {
return (
<input type='text' ref={this.props.Ref} />//6.Ref最终传给了input元素的ref
)
}
}
// 定义一个高阶组件, 目的是将参数上加上value
function hoc (Component) {
class Hoc extends React.Component {
constructor(props) {
super(props)
this.val = "我是你爸爸"
}
render () {
const { forwardedRef, ...rest } = this.props
return (
<Component value={this.val} Ref={forwardedRef} {...rest} />//5.forwardedRef传给了高阶组件的参数的Ref
)
}
}
return React.forwardRef((props, ref) => { //3.获得this.input
return <Hoc {...props} forwardedRef={ref} />;//4.this.input传递给了forwardedRef
});
}
// 组合高阶组件
let SuperInput = hoc(Input)
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
this.input = React.createRef() //1.创建
}
handleClick () {
// console.log(this.input.current);
this.input.current.focus()
}
render () {
return (
<div>
<SuperInput ref={this.input} /> //2.传给ref
<button onClick={this.handleClick}>点击聚焦</button>
</div>
)
}
}
这个传递还是比较丧心病狂的,表达能力有限,希望各位能够从我标的ref的传递顺序中了解这个api。