目录
- 1,介绍
- 2,类组件如何使用
- 4,应用场景-高阶组件HOC
1,介绍
上篇文章中提到,ref
只能对类组件使用,不能对函数组件使用。
而 ref
转发可以对函数组件实现类似的功能。
使用举例:
import React, { Component } from "react";
function CompA(props, ref) {
return (
<h1>
<div ref={ref}>组件A</div>
<span>{props.desc}</span>
</h1>
);
}
const NewCompA = React.forwardRef(CompA);
export default class App extends Component {
refA = React.createRef();
componentDidMount() {
console.log(this.refA);
}
render() {
return <NewCompA ref={this.refA} desc="测试"></NewCompA>;
}
}
打印结果
解释:
通过 React.forwardRef()
来实现 ref
转发。其实就是通过 HOC:参数为组件,返回新组件。
特点:
- 参数只能是函数组件,并且该函数接收2个参数:
- 参数一不变,依旧是
props
; - 参数二就是一个
ref: {current: null}
,也就是React.forwardRef()
返回的新组件接收的ref
属性。它让使用者来决定作为谁的引用。比如上面的例子中,就作为一个子元素的引用。
- 参数一不变,依旧是
- 返回的新组件,和原来的函数组件没有任何区别,只是可以传递
ref
属性了。
2,类组件如何使用
既然明确规定了 React.forwardRef()
的参数只能是函数,该函数的参数也是确定的,那可以将类组件包装一层来达到目的。
更改上面的例子如下:
class CompA extends Component {
render() {
return (
<h1>
<div ref={this.props.forwardRef}>组件A</div>
<span>{this.props.desc}</span>
</h1>
);
}
}
// forwardRef 这个属性名是随意的,只是约定俗成为这个单词了。
const NewCompA = React.forwardRef((props, ref) => {
return <CompA {...props} forwardRef={ref}></CompA>;
});
4,应用场景-高阶组件HOC
在之前的高阶组件HOC中,有个问题没有解决:
const Alog = withLog(CompA)
此时使用的是
Alog
组件,那如何获取原组件CompA
的方法和属性呢?
对Alog
使用ref
获取的并不是是CompA
的组件实例。
可以使用 ref 转发解决:
源代码:
export default function withLog(Comp) {
return class LogWrapper extends Component {
componentDidMount() {
console.log(`${Comp.name}组件被创建了`);
}
componentWillUnmount() {
console.log(`${Comp.name}组件被销毁了`);
}
render() {
return <Comp {...this.props} />;
}
};
}
修改后:
import React, { Component } from "react";
export default function withLog(Comp) {
class LogWrapper extends Component {
componentDidMount() {
console.log(`${Comp.name}组件被创建了`);
}
componentWillUnmount() {
console.log(`${Comp.name}组件被销毁了`);
}
render() {
const { forwardRef, ...rest } = this.props;
return <Comp ref={forwardRef} {...rest} />;
}
}
return React.forwardRef((props, ref) => {
return <LogWrapper {...props} forwardRef={ref}></LogWrapper>;
});
}
这样在使用 withLog
时,并不会影响对源组件 ref
的获取。
以上。