React 第十六章 Ref转发

2024-05-03 11:12

本文主要是介绍React 第十六章 Ref转发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在 React 中,ref 是用来获取组件或者 DOM 元素的引用的一种机制。通过 ref ,你可以在函数组件中直接访问子组件的实例或者访问 DOM 元素。

然而,在某些情况下,你可能需要将 ref 传递给组件中的子组件,或者将 ref 传递到具有特定方法的 DOM 元素上。这就是 React ref 转发的作用。

React ref 转发允许某个组件接收一个 ref,并将其转发给其子组件中指定的 DOM 元素或组件。这样,你就可以在父组件中通过 ref 直接访问子组件的 DOM 元素或实例。

要实现 ref 转发,你需要在子组件中使用 React.forwardRef() 方法来创建一个新的组件,该方法接收一个回调函数作为参数。在这个回调函数中,你可以将传递给子组件的 ref 转发到子组件内部的某个 DOM 元素或子组件上。

下面是一个使用 React ref 转发的示例:

import React, { Component } from 'react'import withLogin from "./HOC/withLog";
import ChildCom1 from "./components/ChildCom1"
const NewChild = withLogin(ChildCom1);export default class App extends Component {constructor() {super();this.comRef = React.createRef();this.state = {show: true}}clickHandle = () => {// 查看当前的 Ref 所关联的组件console.log(this.comRef);}render() {return (<div><button onClick={() => this.setState({show: !this.state.show})}>show/hide</button><button onClick={this.clickHandle}>触发子组件方法</button>{this.state.show ? <NewChild ref={this.comRef} /> : null}</div>)}
}
// withLog.js
import { Component } from "react";
import { formatDate } from "../utils/tools";// 高阶组件是一个函数,接收一个组件作为参数
// 返回一个新的组件
function withLog(Com) {// 返回的新组件return class extends Component {constructor(props) {super(props);this.state = { n: 1 };}componentDidMount() {console.log(`日志:组件${Com.name}已经创建,创建时间${formatDate(Date.now(),"year-time")}`);}componentWillUnmount() {console.log(`日志:组件${Com.name}已经销毁,销毁时间${formatDate(Date.now(),"year-time")}`);}render() {return <Com {...this.props} />;}};
}export default withLog;
// ChildCom1.jsx
import React, { Component } from 'react'export default class ChildCom1 extends Component {test = () => {console.log("这是子组件的 test 方法");}render() {return (<div>ChildCom1</div>)}
}

在上面的三段代码中,我们使用了 withLog 这个高阶组件来包裹 ChildCom1 子组件,从而添加日志功能。在使用由高阶组件返回的增强组件时,我们传递了一个 Ref,我们的本意是想要这个 Ref 关联原本的子组件,从而可以触发子组件里面的方法。

但是我们会发现 Ref 关联的是高阶组件中返回增强组件,而非原来的子组件。

image-20221130135500947

要解决这个问题就会涉及到 Ref 的转发。说直白一点就是 Ref 的向下传递给子组件。

这里 React 官方为我们提供了一个 React.forwardRef API。我们需要修改的仅仅是高阶组件:

import React, { Component } from "react";
import { formatDate } from "../utils/tools";// 高阶组件是一个函数,接收一个组件作为参数
// 返回一个新的组件
function withLog(Com) {// 返回的新组件class WithLogCom extends Component {constructor(props) {super(props);this.state = { n: 1 };}componentDidMount() {console.log(`日志:组件${Com.name}已经创建,创建时间${formatDate(Date.now(),"year-time")}`);}componentWillUnmount() {console.log(`日志:组件${Com.name}已经销毁,销毁时间${formatDate(Date.now(),"year-time")}`);}render() {// 通过 this.props 能够拿到传递下来的 ref// 然后和子组件进行关联const {forwardedRef, ...rest} = this.props;return <Com ref={forwardedRef} {...rest} />;}}return React.forwardRef((props, ref) => {// 这里是关键,渲染函数会自动传入 ref,然后我们将 ref 继续往下传递return <WithLogCom {...props} forwardedRef={ref} />;});
}export default withLog;

在上面的代码中,React.forwardRef 接受一个渲染函数,该函数接收 propsref 参数并返回原本我们直接返回的增强组件。

接下来我们在增强组件的 render 方法中,通过 this.props 拿到 ref 继续传递给子组件。

那么 React.forwardRef 究竟做了啥呢?源码如下:

image-20221130135525552

可以看到,实际上 forwardRef 这个静态方法实际上也就是返回一个 elementType 的对象而已,该对象包含一个 render 方法,也就是我们在使用 React.forwardRef 时传入的渲染函数。

之所以要这么多此一举,是因为该渲染函数会自动传入 propsref,关键点就在这里,拿到 ref 后,后我们就可以将 ref 继续往下面传递给子组件。

总结来说,React ref 转发是一种将 ref 从一个组件传递到另一个组件的技术,通过它可以在父组件中直接访问子组件的 DOM 元素或实例。

这篇关于React 第十六章 Ref转发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956610

相关文章

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F