当前位置: 首页 > news >正文

react forwardRef和readux的connect冲突,导致ref.current获取不到值

问题描述:

forwardRef和readux的connect冲突,导致ref.current获取不到值
我想封装一个组件,父组件调用子组件的方法。但因为组件里使用了redux的connect导致ref一直获取不到值。

import React, { useState, useEffect, ReactNode, forwardRef, useImperativeHandle } from 'react';
import { Modal} from 'antd';import { connect } from 'react-redux'
import * as actions from '@/store/actions'
import "./index.less";interface Props {/** 标题内容 */title?: string | ReactNode;/** 操作类型 */type: "add" | "edit";/** 数据 */fundData?: any;storeData?: any;setStoreData?: any;children?: ReactNode;}
/** * 策略弹窗表单 * 本组件可传一children点击传入的children来控制弹窗打开* 还可以用ref 来控制弹窗打开和关闭* 父组件引用useRef const modalRef:any = useRef(); modalRef.current?.openModal();* 然后<ClModalForm type="edit" fundData={{}} ref={modalRef}/>* 
*/const ClModalForm = forwardRef((props: Props, ref) => {const { title, children } = props;//编辑策略 Modal是否展示const [cl, setCl] = useState(false);// 暴露 openModal、handleCancel 方法给父组件useImperativeHandle(ref, () => ({openModal,handleCancel,}));const handleCancel = () => {setCl(false);};/** 打开弹窗 */const openModal = () => {setCl(true);};return (<div>{children && <div onClick={openModal}>{children}</div>}<Modal title={title || "编辑策略"}visible={cl}onCancel={handleCancel}width={560}destroyOnClosebodyStyle={{maxHeight: "70vh",  // 控制最大高度overflowY: "auto",  // 垂直滚动}}centered></Modal></div>)
});
export default connect((state) => state, actions)(ClModalForm);

使用:

const modalRef: any = useRef();
<ClModalForm title={"补充策略信息"} type="edit" fundData={currentRow} ref={modalRef} />然后
if(modalRef.current){modalRef.current?.openModal();
}

问题原因:

1.Redux connect 会阻断 ref 转发,默认不会向下传递 ref。

2.直接使用 connect(…)(forwardRef(…)) 时,ref 会被高阶组件拦截。

解决方案:

方案适用场景优点缺点
1. forwardRef配置React Redux 6+最简洁官方方案需要较新版本
2. 双forwardRef所有版本通用性强代码稍复杂
3. 自定义ref属性简单场景无需高阶组件非标准ref用法
4. withRefRedux 5.x旧版兼容方案已弃用

方案一:最佳实践 - 使用 React Redux 的 forwardRef 配置(推荐):

导出把ref透传打开:

export default connect((state) => state, actions, null,{ forwardRef: true } // 显式启用 ref 不加父组件拿不到子组件的ref
)(ClModalForm);或者:
// 解决方案:添加 { forwardRef: true } 配置
const ConnectedClModalForm = connect((state) => state,actions,null,{ forwardRef: true }  // 关键配置
)(ClModalForm);export default ConnectedClModalForm;

redux版本<6请看方案四!
版本兼容性注意事项:
v6.0 以下:必须用 { withRef: true },并通过 getWrappedInstance() 间接访问 ref1。
v6.0 及以上:优先使用 { forwardRef: true },直接获得 ref 引用。

方案二:双 forwardRef 包裹法:

两层转发:

const InnerClModalForm = forwardRef<ModalHandles, Props>((props, ref) => {// ...组件内部逻辑不变
});const Connected = connect((state) => state, actions)(InnerClModalForm);// 外层 forwardRef 处理
const ClModalForm = forwardRef<ModalHandles, Props>((props, ref) => (<Connected {...props} forwardedRef={ref} />
));export default ClModalForm;

方案三:自定义 ref 属性传递:

interface Props {innerRef?: React.Ref<ModalHandles>;// ...其他props
}const ClModalForm = (props: Props) => {// 使用 props.innerRef 替代 refuseImperativeHandle(props.innerRef, () => ({openModal,handleCancel}));// ...组件内部逻辑不变
};export default connect((state) => state, actions)(ClModalForm);// 父组件使用方式
function Parent() {const ref = useRef<ModalHandles>(null);return <ClModalForm innerRef={ref} />;
}

方案四:使用 withRef 选项(旧版 React Redux):

// 适用于 React Redux 5.x 及以下版本
const ConnectedClModalForm = connect((state) => state,actions,null,{ withRef: true }  // 旧版配置
)(forwardRef(ClModalForm));export default ConnectedClModalForm;
http://www.xdnf.cn/news/1060255.html

相关文章:

  • infinisynapse 使用清华源有问题的暂时解决方法:换回阿里云源并安装配置PPA
  • 【MySQL基础】MySQL内置函数全面解析:提升你的数据库操作效率
  • AWK在网络安全中的高效应用:从日志分析到威胁狩猎
  • 苍穹外卖-2025 完成基础配置环节(详细图解)
  • 【嵌入式硬件实例】-555定时器控制舵机/伺服电机
  • 力扣网C语言编程题:接雨水(动态规划实现)
  • SCRM软件数据分析功能使用指南:从数据挖掘到商业决策
  • 什么是Nacos
  • TDengine 集群超能力:超越 InfluxDB 的水平扩展与开源优势
  • jquery 赋值时不触发change事件解决——仙盟创梦IDE
  • repo 工具
  • 动态规划笔记
  • FastMCP框架进行MCP开发:(一)基础环境搭建及测试
  • 云XR(AR/VR)算力底座关键特征与技术路径
  • 颈部不自主偏移现象解析
  • systemverilog中关于多线程的若干思考
  • SAP LPD(launchpad)配置使用手册
  • C#学习13——正则表达式
  • 计算机网络学习笔记:TCP可靠传输实现、超时重传时间选择
  • leetcode 2294. 划分数组使最大差为 K 中等
  • Kernel K-means:让K-means在非线性空间“大显身手”
  • 机器学习×第十二卷:回归树与剪枝策略——她剪去多余的分支,只保留想靠近你的那一层
  • Arduino Nano 33 BLE Sense Rev 2开发板使用指南之【环境搭建 / 点灯】
  • 基于微信小程序和深度学习的宠物照片拍摄指导平台的设计与实现
  • 【AI编程】第3期,针对AI生成的改枪码列表创建对应的数据库表
  • 主成分分析(PCA)例题——给定协方差矩阵
  • 关于嵌入式编译工具链与游戏移植的学习
  • 【图论 DFS搜索树】P10298 [CCC 2024 S4] Painting Roads|普及+
  • threejs 实现720°全景图,;两种方式:环境贴图、CSS3DRenderer渲染
  • 问题排查之nginx请求日志