首页 > 其他分享 >Ant-Design modal对话框未打开时,无法通过uesRef获取modal内部元素DOM节点

Ant-Design modal对话框未打开时,无法通过uesRef获取modal内部元素DOM节点

时间:2023-11-29 17:57:23浏览次数:43  
标签:const modal DOM data 对话框 visible Modal return ref

为什么要记录下来呢?因为我在网上和chatGpt上没有搜到合适的解决方案。在CDNS上看到个和我遇到问题一样的,居然要收费才能看,所以自己记下来。当然肯定还有其他的好方案,欢迎大家留言。

需求:使用antdV/g6画关系图,类似于企查查上面的那样:点击按钮 打开Modal框,把数据渲染到 Modal框的div上。

 遇到的问题:打开Modal时,图渲染不上去,打印ref.current是null,关闭Modal框后,打印的ref.current是 div元素

**以下是父组件代码: 结构图按钮实际是在表格行内的,这里只是模拟**

import React, { useEffect, useState } from 'react';
import { message } from 'antd';
import { StructureGraph } from '@/components/GlobalComponents';
const [imgVisible, setImgVisible] = useState(false); // 结构图弹窗
const [curClickRowData, setCurClickRowData] = useState({}); // 点击的当前行数据
const [imgData, imgLoading, onRequestImg] = useServiceApi(qryProductStructureGraph);

export const ProductInvestmentStatement = () => {
        // 点击结构图按钮
      const handleClickStructure = (record:any) => {
        setCurClickRowData(record);
        onRequestImg({
          productId: record.productId,
        }).then((res) => {
          if (res?.tradeNode?.tradeNodeVo) {
            setImgVisible(true);
          } else {
            message.error('此项目还没有结构图!');
          }
        });
      };
      
      return <>
          <div onClick={handleClickStructure}>结构图</div>
          <StructureGraph
            structureData={imgData?.tradeNode || {}}
            loading={imgLoading}
            id={curClickRowData.productId}
            name={curClickRowData.displayShortName}
            visible={imgVisible}
            onCancel={() => setImgVisible(false)}
          />
      </>
  }

 

接下来是子组件代码,已去掉图相关的代码  

import React, { useEffect, useRef, useMemo, useState } from 'react';
import { ConfirmModal } from '@/components/GlobalComponents'; // 其实就是antd的Modal框封装了一下样式

export const StructureGraph = ({ structureData, id, visible, onCancel, name }) => {
// 这里使用自定义hook对接口数据做相关的处理
  const data = useMemo(() => traverse(structureData, id), [structureData]);
  const ref = useRef<HTMLDivElement>(null);
    useEffect(() => {
        if (!data || !Object.keys(data).length) return;
        if (ref?.current) {
          console.log(ref?.current, '3333333333');
        }
    }, [data, visible]);
    
    return (<ConfirmModal
    modalWidth="1140px"
    visible={visible}
    title={`${name} 结构图`}
    cancelText="关闭"
    onCancel={onCancel}
    noOkBtn
  >
    <div style={{ width: '100%', height: 500, userSelect: 'none' }} ref={ref} />
  </ConfirmModal>);
}

  

 

由以上可以看到,Modal框没有渲染在DOM上,但是你的组件其实已经渲染了,这种情况是拿不到 div的ref的。

第一种解决方案: visible为false时,整个组件return null; 但是这样Modal框关闭的动效就没有了,UI应该不能接受。

import React, { useEffect, useRef, useMemo, useState } from 'react';
import { ConfirmModal } from '@/components/GlobalComponents'; // 其实就是antd的Modal框封装了一下样式

export const StructureGraph = ({ structureData, id, visible, onCancel, name }) => {
// 这里使用自定义hook对接口数据做相关的处理
  const data = useMemo(() => traverse(structureData, id), [structureData]);
  const ref = useRef<HTMLDivElement>(null);
    useEffect(() => {
        if (!data || !Object.keys(data).length) return;
        if (ref?.current) {
          console.log(ref?.current, '3333333333');
        }
    }, [data, visible]);
    
   // 加上这个就可以了。 但是这样Modal框关闭的动效就没有了
   if (!visible) {
      return null; // 不渲染 Modal
   }
    
    return (<ConfirmModal
    modalWidth="1140px"
    visible={visible}
    title={`${name} 结构图`}
    cancelText="关闭"
    onCancel={onCancel}
    noOkBtn
  >
    <div style={{ width: '100%', height: 500, userSelect: 'none' }} ref={ref} />
  </ConfirmModal>);
}

 第二种解决方案: 使用useState新建个newRef,监听这个元素 Modal框动效正常 

 

export const StructureGraph = ({ structureData, id, visible, onCancel, name }) => {
// 这里使用自定义hook对接口数据做相关的处理
  const data = useMemo(() => traverse(structureData, id), [structureData]);
  const ref = useRef<HTMLDivElement>(null);
  const [newRef, setNewRef] = useState(ref); // 通过多创建一个ref,来解决 Modal框未渲染时,拿不到div的问题
  
    useEffect(() => {
        if (!data || !Object.keys(data).length) return;
        if (ref?.current) {
          console.log(ref?.current, '3333333333');
        }
    }, [data, newRef]); //这里监听newRef
    
    useEffect(() => {
    if (visible) {
      setNewRef(ref);
    } else {
      setNewRef(null);
    }
  }, [visible]);
    
    return (<ConfirmModal
    modalWidth="1140px"
    visible={visible}
    title={`${name} 结构图`}
    cancelText="关闭"
    onCancel={onCancel}
    noOkBtn
  >
    <div style={{ width: '100%', height: 500, userSelect: 'none' }} ref={ref} />
  </ConfirmModal>);
}

 

 最后上图:

 

 

标签:const,modal,DOM,data,对话框,visible,Modal,return,ref
From: https://www.cnblogs.com/zpy521hl/p/17865468.html

相关文章

  • TypeError: Cannot read properties of undefined (reading '$modal')
    原代码:handleFinish(row){this.$modal.confirm('确认录取学生编号为"'+row.stuCode+'"的成绩?').then(function(){finishStudentScore({id:row.id}).then((response)=>{if(response.code==......
  • [ABC277G] Random Walk to Millionaire 题解
    题目链接点击打开链接题目解法首先\(O(n^3)\)的\(dp\)是显然的,令\(f_{i,j,k}\)为第\(i\)步在\(j\),当前等级为\(k\)的\([i,n]\)步获得钱数的期望,转移枚举出边即可一个很妙的优化是:贡献都是\(k^2\)的形式,所以我们考虑维护\(k\)的\(0,1,2\)次幂,即\(\sum,\sum......
  • 学习Vue3 第五章(Vue核心虚拟Dom和 diff 算法)
      介绍虚拟DOM虚拟DOM就是通过JS来生成一个AST节点树   为什么要有虚拟DOM?一个dom上面的属性是非常多的,所以直接操作DOM非常浪费性能介绍Diff算法diff算法的目的就是找出新旧不同虚拟DOM之间的差异,使最小化的更新视图,所以diff算法本质上就是......
  • 7 Mutilmodal Feature Extraction and Attention-based Fusion for Emotion Estimatio
    摘要。人机交互技术的不断进步,使得情感的计算成为可能。在本文中,我们介绍了我们提交给CVPR2023竞赛的情感行为分析在野外(ABAW)。人机交互中的情感分析应尽可能从多维度入手,填补单个不完善的情感通道,最后通过拟合多个结果确定情感倾向。因此,我们利用了从比赛数据集中不同长度的视......
  • 神经网络入门篇:详解随机初始化(Random+Initialization)
    当训练神经网络时,权重随机初始化是很重要的。对于逻辑回归,把权重初始化为0当然也是可以的。但是对于一个神经网络,如果把权重或者参数都初始化为0,那么梯度下降将不会起作用。来看看这是为什么。有两个输入特征,\(n^{[0]}=2\),2个隐藏层单元\(n^{[1]}\)就等于2。因此与一个隐藏层......
  • MFC 删除隐藏对话框中的蓝色参考虚线
    ▲对话框中的蓝色参考虚线▲选择"格式"--"切换辅助线"......
  • 【4.0】常用模块之random模块
    【一】导入模块importrandom【二】随机小数【1】默认区间的小数(random)大于0且小于1之间的小数importrandom#默认是大于0且小于1之间的小数res=random.random()print(res)#0.24512653841495302【2】指定区间的小数(uniform)importrandom#指定为0到......
  • CF685E Travelling Through the Snow Queen's Kingdom
    题意给定一张图,走出当前边的时间为\(i\)。\(q\)次询问,问\(s\)是否能在\(l\tor\)中走到\(t\)。Sol考虑将边从大到小插入图中。注意到当前边只能对起点造成贡献。复杂度\(O(n\times\max\{n,m\})\)Code#include<iostream>#include<algorithm>#include<cstd......
  • [WPF]动手写一个简单的消息对话框
    消息对话框是UI界面中不可或缺的组成部分,用于给用户一些提示,警告或者询问的窗口。在WPF中,消息对话框是系统原生(user32.dll)的MessageBox,无法通过Style或者Template来修改消息对话框的外观。因此,当需要一个与应用程序主题风格一致的消息对话框时,只能自己动手造轮子了。确定“轮子”......
  • Chinese Wisdom on Sewage Treatment in India
    ChinaprogramComprehensivelycontrolpollutantemissions(1)Paycloseattentiontothepreventionandcontrolofindustrialpollution.Banthe"tensmall"enterprises.Comprehensivelyinvestigatesmallindustrialenterpriseswithlowequipme......