【解决方案】【最佳实践】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

相关文章

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决