一、ref转发
前面我们将ref时提到了,ref并不能作用于函数组件,因为react觉得函数组件只返回一个dom并没有多大意义。那么如果我们一定要对函数组件使用ref怎么办呢?
1、函数组件转发
import React, {
Component } from 'react'
function A(props) {
return (
<div>
<span>{
props.words}</span>
</div>
)
}
export default class App extends Component {
hRef = React.createRef()
ARef = React.createRef()
componentDidMount() {
console.log(this);
}
render() {
return (
<div>
<A ref={
this.ARef} words="abcd" />
<h1 ref={
this.hRef}>类组件</h1>
</div>
)
}
}
此时我们声明两个ref绑定在函数组件A和h1
标签上,果然系统提示ref不能作用于函数组件,而输出结果也显示只有h1
通过ref转发后
import React, {
Component } from 'react'
function A(props, ref) {
return (
<div>
<span ref={
ref}>{
props.words}</span>// 将传进来的ref绑定在span上
</div>
)
}
//传递函数组件A,得到一个新组件NewA
const NewA = React.forwardRef(A)
export default class App extends Component {
hRef = React.createRef()
ARef = React.createRef()
componentDidMount() {
console.log(this);
}
render() {
return (
<div>
<NewA ref={
this.ARef} words="abcd" />
<h1 ref={
this.hRef}>类组件</h1>
</div>
)
}
}
forwardRef方法:
1. 参数,传递的是函数组件,不能是类组件,并且,函数组件需要有第二个参数来得到ref
2. 返回值,返回一个新的组件
2、类组件转发
import React, {
Component } from 'react'
class A extends Component {
render() {
return (
<div>
<span ref={
this.props.ref1}>{
this.props.words}</span>
</div>
)
}
}
export default class App extends Component {
hRef = React.createRef()
ARef = React.createRef()
componentDidMount() {
console.log(this);
}
render() {
return (
<div>
<A ref1={
this.ARef} words="abcd" />
<h1 ref={
this.hRef}>类组件</h1>
</div>
)
}
}
类组件中我们可以通过属性的方式传递ref(ref不是属性),但这明显不是我们想要的转发。
这里我们可以利用forwardRef
通过函数的方式返回类组件A,从而实现转发
import React, {
Component } from 'react'
class A extends Component {
render() {
return (
<div>
<span ref={
this.props.abc}>{
this.props.words}</span>
</div>
)
}
}
const NewA = React.forwardRef((props, ref) => {
return <A {
...props} abc={
ref} />
})
export default class App extends Component {
hRef = React.createRef()
ARef = React.createRef()
componentDidMount() {
console.log(this);
}
render() {
return (
<div>
<NewA ref={
this.ARef} words="abcd" />
<h1 ref={
this.hRef}>类组件</h1>
</div>
)
}
}
那么通过转发我们可以做什么呢?
3、实例
在前面我们学习了高阶组件,那么我们如果直接对高阶组件使用ref会怎么样。
import React from 'react'
import {
A } from "./components/Comps";
import withLog from "./HOC/withLog";
let AComp = withLog(A);
export default class App extends React.Component {
myRef = React.createRef();
componentDidMount() {
console.log(this.myRef);
}
render() {
return (
<div>
<AComp ref={
this.myRef} isLogin a={
1} />
</div>
)
}
}
高阶组件withLog中我们只是想对A组件进行功能增能,但是后续使用中我们仍然想对A组件使用ref怎么办呢?
import React from "react"
/**
* 高阶组件
* @param {*} comp 组件
*/
export default function withLog(Comp) {
class LogWrapper extends React.Component {
componentDidMount() {
console.log(`日志:组件${
Comp.name}被创建了!${
Date.now()}`);
}
componentWillUnmount() {
console.log(`日志:组件${
Comp.name}被销毁了!${
Date.now()}`);
}
render() {
//正常的属性
//forwardRef代表要转发的ref {current:null}
const {
forwardRef, ...rest } = this.props;
return (
<>
<Comp ref={
forwardRef} {
...rest} />
</>
)
}
}
return React.forwardRef((props, ref) => {
return <LogWrapper {
...props} forwardRef={
ref} />
})
}
通过转发就可以做到了。
转载:https://blog.csdn.net/xun__xing/article/details/116422253
查看评论