react学习—ref转发

一、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} />
    })
}

通过转发就可以做到了。
在这里插入图片描述
博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞羽逐星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值