Ref 转发

1 是什么

Ref 转发指组件接收 ref 参数,并将 ref 参数传递给子节点。

2 解决什么问题

解决需要在组件外部对组件内部节点进行管理的问题。

3 使用

  • 只有通过 React.forwardRef 创建的组件,才有获取和转发 ref 的能力。普通组件的 props 中不存在 ref 属性,组件内部也获取不到 ref 参数。
  • ref 转发控制的节点既可以是原生的 DOM 节点,也可以是 React 组件。

3.1 转发 Ref 到内部节点

1
2
3
4
5
6
7
8
9
10
// 通过 React.forwardRef 函数创建的组件,才能接收到外部的 ref 属性,
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));

// 你可以直接获取 DOM button 的 ref:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

3.2 在高阶组件中转发 Ref

高阶组件默认无法透传 ref 属性给被包装组件,可以通过使用 React.forwardRef 来创建高阶组件的返回值以达到透传 ref 属性的能力。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react';
import ReactDOM from 'react-dom';

function logProps(WrappedCompoonents){
class LogProps extends React.Component{
componentDidUpdate(prevProps){
console.log('old props', prevProps);
console.log('new props', this.props);
}
render(){
// 3、提取 forward 属性
const {forward, ...rest} = this.props;
// 4、将 forward 配置给被包装组件的 ref
return <WrappedCompoonents ref={forward} {...rest}></WrappedCompoonents>
}
}
// 1、通过 React.forwardRef 创建有接受 ref 参数能力的组件
return React.forwardRef((props, ref)=>{
//2、 将 ref 属性值通过属性 forward 传递给包装组件
return <LogProps {...props} forward={ref}></LogProps>
})
}