react之转发ref

React之转发ref

react.16.3新增了forwardRef Api 用来转发ref到子组件上
这里大致说下两种情况

  1. 纯组件不能使用ref
  2. 如何给使用了高阶函数包裹的组件加上ref

针对以上两种情况 我们看看这个新的api

纯组件

纯组件是不需要ref属性的 我们可以使用React.forwardRef将父组件加的ref转发到input里

harmony
1
2
3
const ForwardRefButton = React.forwardRef((props, ref) => (
<input {...props} ref={ref} />
))
高阶组件

我们先声明一个高阶组件hoc

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function hoc() {
return function (WrapperComponent) {
class HOC extends React.Component {
render() {
return <div className="hoc-wrapper">
<WrapperComponent
{...this.props}
ref={this.props.forwardRef}
/>
</div>
}
}

return HOC
}
}

再写一个正常组件

harmony
1
2
3
4
5
class ButtonRef extends React.Component {
render() {
return <button>测试高阶函数转发ref</button>
}
}
harmony
1
const HocButton = hoc()(ButtonRef)

HocButton 是我们通过高阶组件包装过的组件
这时候高阶组件没有进行ref转发 导致我们给HocButton添加ref属性的时候 只能添加到HOC这个组件上
想要ButtonRef也拥有这个属性 我们得改一下高阶函数的返回值 如下:

harmony
1
2
3
return React.forwardRef((props, ref) => (
<HOC {...props} forwardRef={ref} />
))

这样就能正常访问到被高阶组件包裹的子组件啦

有没有办法不使用forwardRef就能做到ref转发呢?
当然有 可以把ref当做做个属性传进高阶函数 再经由高阶组件注册到子组件上 也能实现ref转发啦 还是上面的例子
我们再使用HocButton时

harmony
1
2
3
4
5
6
handleRef(el) {
this.buttonRef = el
}
render() {
<HocButton wrappedref={this.handleRef.bind(this)} />
}

改一下高阶组件内部调用 如下:

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function hoc() {
return function (WrappedComponent) {
class HOC extends React.Component {
render() {
return <div className="hoc-wrapper">
<WrappedComponent
{...this.props}
ref={this.props.wrappedref}
/>
</div>
}
}
return HOC
}
}

这样也是实现ref转发到WrappedComponent上啦