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

相关文章

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

python解析HTML并提取span标签中的文本

《python解析HTML并提取span标签中的文本》在网页开发和数据抓取过程中,我们经常需要从HTML页面中提取信息,尤其是span元素中的文本,span标签是一个行内元素,通常用于包装一小段文本或... 目录一、安装相关依赖二、html 页面结构三、使用 BeautifulSoup javascript

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06