React@16.x(12)ref 转发-forwardRef

server/2024/12/23 3:14:28/

目录

  • 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 的获取。


以上。


http://www.ppmy.cn/server/46866.html

相关文章

MFC工控项目实例之二添加iPlotx控件

承接专栏《MFC工控项目实例之一主菜单制作》 在WIN10下使用Visual C 6.0 &#xff08;完整绿色版&#xff09;添加iPlotx控件的方法。 1、在资源主对话框界面点击鼠标右键如图选择插入Active控件点击进入。 2、选择iPlotx Contrlolh点击确定。 3、在对话框界面插入iPlotx控件。…

【ECMAScript 详解:现代 JavaScript 的核心】

ECMAScript 详解 ECMAScript 是 JavaScript 的官方标准&#xff0c;它定义了 JavaScript 的核心语法和功能。在这篇文章中&#xff0c;我们将深入探讨 ECMAScript 的各个方面&#xff0c;包括历史背景、语言特性、新功能和未来发展趋势。 目录 介绍 什么是 ECMAScript&#x…

linux 查看 线程名, 线程数

ps -T -p 3652 ps H -T <PID> ps -eLf | grep process_name top -H -p <pid> 查看进程创建的所有线程_ps 显示一个进程的所有线程名字-CSDN博客

使用Bash脚本确保定时任务的单例执行

简介&#xff1a; 在Linux系统中&#xff0c;定时任务是自动化运维的重要组成部分。然而&#xff0c;有时候我们可能需要确保某个定时任务在任何给定时间点只运行一次&#xff0c;以避免资源冲突或数据不一致。本文将介绍如何使用Bash脚本和文件锁来实现单例定时任务。 什么是…

轻松拿捏C语言——【文件操作】

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 目录 &#x1f…

JVM双亲委派模型

在之前的JVM类加载器篇中说过&#xff0c;各个类加载器都有自己加载的范围&#xff0c;比如引导类加载器只加载Java核心库中的class如String&#xff0c;那如果用户自己建一个包名和类名与String相同的类&#xff0c;会不会被引导类加载器加载。可以通过如下代码测试&#xff0…

【文末附gpt升级秘笈】OpenAI的治理结构

OpenAI的治理结构具有其独特性和复杂性&#xff0c;以下是关于其治理结构的详细描述&#xff1a; 组织形态&#xff1a; OpenAI成立于2015年&#xff0c;是一家美国人工智能研究公司&#xff0c;旨在实现安全的通用人工智能&#xff08;AGI&#xff09;并让其有益于人类。组织…

Vivado的两种下载安装方式:Webpack下载与安装、本地文件安装详细步骤讲解

目录 1.前言2. Vivado Webpack下载、安装3.本地文件下载安装 微信公众号获取更多FPGA相关源码&#xff1a; 1.前言 本人自本科大二开始接触FPGA相关知识&#xff0c;现已将近六年&#xff0c;由于一直在上学&#xff0c;也不是一直在搞FPGA&#xff0c;但是也完成过一些项目…