【解决方案】【最佳实践】React高阶组件中Refs 不会被传递的问题

本文主要是介绍【解决方案】【最佳实践】React高阶组件中Refs 不会被传递的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是DX3906。

最近遇到React高阶组件中Refs 不会被传递的问题。

在这里总结一下解决方案和解决思路:主要是通过从内向外从外向内2种思路来分析解决的。

目录

前言

解决方案一:React.forwardRef

解决方案二:使用props传递ref

结语


前言

        虽然高阶组件的约定是将所有 props 传递给被包装组件,但这对于 refs 并不适用。那是因为 ref 实际上并不是一个 prop - 就像 key 一样,它是由 React 专门处理的。如果将 ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。

        在React中,Ref是一个React对象,它用于访问DOM节点或组件实例。当你使用高阶组件封装组件时,被封装的组件的Ref可能不会被传递到高阶组件的外部。这是因为高阶组件创建了一个包装组件,它接收原始组件作为prop,并且通常会创建一个新的ref来引用它。

解决方案一:React.forwardRef

        解决这个问题的方法之一是使用React的React.forwardRef函数。forwardRef允许你将一个ref传递给子组件,这样即使组件被高阶组件封装,ref也能正确地传递到最底层的组件。

下面是一个使用React.forwardRef的示例:

import React, { forwardRef } from 'react';const EnhancedComponent = React.forwardRef((props, ref) => {// 将ref传递给被封装的组件return <WrappedComponent {...props} forwardedRef={ref} />;
});const WrappedComponent = forwardRef((props, forwardedRef) => {// 使用forwardedRef来访问DOM或组件实例return <div ref={forwardedRef}>...</div>;
});// 使用时,ref将被传递到WrappedComponent的div元素
const ref = React.createRef();
<EnhancedComponent ref={ref} />;

        在这个例子中,EnhancedComponent是一个高阶组件,它使用forwardRef来接收一个ref,并将其传递给WrappedComponentWrappedComponent也使用forwardRef来接收这个ref,并将其应用到内部的DOM元素上。

        使用forwardRef可以确保无论组件被多少层高阶组件封装,ref都能正确地传递到最底层的组件。这使得你可以在需要的时候访问DOM节点或组件实例,而不受高阶组件的影响。

解决方案二:使用props传递ref

    第一步:我们把ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。

    第二步:在HOC 把被组装的组件的ref赋值给高阶组件外层的一个instance对象。然后使用第一步中的ref调用instance对象。

        具体案例如下:

function withSubscription(WrappedComponent, selectData) {return class extends React.Component {constructor(props) {super(props);this.state = {data: selectData(props) // 初始状态};this.instance;}componentDidMount() {// 订阅数据源const { subscribe } = this.props;subscribe(data => this.setState({ data }));}componentWillUnmount() {// 取消订阅const { unsubscribe } = this.props;unsubscribe();}render() {// 将数据和原始props传递给WrappedComponentreturn <WrappedComponent ref={(node)=>{this.instance = node}} {...this.props} />;}};
}
import React,{useEffect,useRef} from "react"
function WithShow(props) {let cusRef = useRef(null);useEffect(()=>{cusRef.current.instance.被包装组件的方法()})// 使用高阶组件const MyComponentWithData = withSubscription(MyComponent, props => {// 根据props选择数据return someDataSource.getData(props.id);});// 然后在你的应用中使用MyComponentWithDatareturn() {// 获取Hoc外层组件的refreturn <MyComponentWithData ref={cusRef} {...this.props} />;}};
}

结语

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~ 

这篇关于【解决方案】【最佳实践】React高阶组件中Refs 不会被传递的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

Vue3 如何通过json配置生成查询表单

《Vue3如何通过json配置生成查询表单》本文给大家介绍Vue3如何通过json配置生成查询表单,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录功能实现背景项目代码案例功能实现背景通过vue3实现后台管理项目一定含有表格功能,通常离不开表单

Java中字符编码问题的解决方法详解

《Java中字符编码问题的解决方法详解》在日常Java开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在Java项... 目录前言背景:为什么会出现编码问题常见场景分析控制台输出乱码文件读写乱码数据库存取乱码解决方案统一使

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu