飞道的博客

react学习—ref转发

294人阅读  评论(0)

一、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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场