react学习—ref转发

ref转发

  • 一、ref转发
    • 1、函数组件转发
    • 2、类组件转发
    • 3、实例

一、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
react学习—ref转发_第1张图片
通过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>
    )
  }
}

react学习—ref转发_第2张图片
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不是属性),但这明显不是我们想要的转发。
react学习—ref转发_第3张图片
这里我们可以利用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>
    )
  }
}

react学习—ref转发_第4张图片
那么通过转发我们可以做什么呢?

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怎么办呢?
react学习—ref转发_第5张图片

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

通过转发就可以做到了。
react学习—ref转发_第6张图片

你可能感兴趣的:(react学习,react,ref)