react Hook+antd封装一个优雅的弹窗组件
前言
在之前学vue2的时候封装过一个全局的弹窗组件,可以全局任意地方通过this调用,这次大创项目是用react技术栈,看了一下项目需求,突然发现弹窗还是比较多的,主要分为基础的弹窗以及form表单式的弹窗,如果只是无脑的去写代码,那些项目也没啥必要了。正好react和hook相结合,去实现一个全局的弹窗组件,便于之后的使用。
心血历程
antd组件的弹窗一般是和我们的代码放一起的,这样就导致复用性比较低,而且也显得代码比较乱。由此我就想过自己封装一个,有了之前使用vue封装的经验,我开始着手封装,基本思路就是创建一个新的div放到页面中,手动的渲染与删除,确定和取消按钮正好对应promise的成功与失败。基本思路没有问题,但是再实行的过程中,首先遇到手动渲染挂载到页面的问题,之后又遇到逻辑放到一起,无法手动控制form表单,最后突然想清楚一点就是,逻辑可以分开,把一个功能的相同点与不同点进行分离,逻辑上要单纯,最后再整合到一起。这样的话可以专注于具体的逻辑功能及实现。
代码
modal.tsx
封装的弹窗具体功能,其中根据类型的不同会用到form的高阶组件
import React, { useCallback, useEffect } from "react";
import ReactDOM from "react-dom/client";
import { Button, Modal } from "antd";
import { useState } from "react";
import { useForm } from "./form";
type PromiseType = {resolve?: any;reject?: any;
};
// modal类型(分为普通或者表单形式)
type modalType = "nomal" | "form";
/*
成功之后的回调函数
显示标题
提示文字(用于普通类型文本提示)
成功文字
配置对象(字段名,规则,默认值)
*/
type modalPropsType = {type?: modalType;title?: string;infoTxt?: string;okTxt?: string;successCallback?: (values?: any) => void;formOptions?: any;
};export const useModal = (props: modalPropsType = {}) => {const {type = "nomal",title = "提示",infoTxt = "这是一段提示",okTxt = "确定",successCallback = () => {},formOptions = [],} = props;const [show, setShow] = useState<boolean>(false);const [promiseRes, setPromiseRes] = useState<PromiseType>();const [containerEle, setContainerEle] = useState<HTMLElement | null>(null);// 节点的挂载与卸载useEffect(() => {if (containerEle) {return;}// 创建挂载节点const div = document.createElement("div");div.id = "myContainer";document.body.append(div);setContainerEle(div);}, [containerEle]);// 卸载节点const unMounted = useCallback(() => {if (containerEle) {document.body.removeChild(containerEle);setContainerEle(null);}}, [containerEle]);const success = useCallback((values: any) => {successCallback && successCallback();promiseRes?.resolve(type === "nomal" ? "确定" : values);setShow(false);unMounted();},[promiseRes, unMounted, successCallback, type],);// 取消const cancel = useCallback(() => {promiseRes?.reject("取消");setShow(false);unMounted();}, [unMounted, promiseRes]);// 获取包装节点const { MyForm } = useForm({ cancel, success, okTxt, options: formOptions });// 挂载节点useEffect(() => {if (!show || !containerEle) {return;}const root = ReactDOM.createRoot(containerEle as HTMLElement);// 根据类型,去判断是简单的弹窗还是form表单root.render(<ModalonCancel={cancel}open={show}onOk={success}destroyOnClose={true}title={title}okText={okTxt}wrapClassName="modal-wrap"cancelButtonProps={{ shape: "round" }}okButtonProps={{ shape: "round" }}width={600}footer={type === "form"? null: [<Button key="success" type="primary" onClick={success}>{okTxt}</Button>,<Button key="cancel" onClick={cancel}>取消</Button>,]}getContainer={containerEle as HTMLElement}>{type === "form" && <MyForm></MyForm>}{type === "nomal" && <p>{infoTxt}</p>}</Modal>,);}, [show,MyForm,cancel,containerEle,title,infoTxt,okTxt,success,type,]);// 初始化const init = () => {setShow(true);return new Promise((resolve, reject) => {setPromiseRes({ resolve, reject });});};return { init };
};
from.tsx
封装的form表单(待完善)
import { Button, Form, FormInstance, Input, Space } from "antd";
import React from "react";
import { useCallback } from "react";/*
传递配置对象()
1. 成功回调
2.失败回调
3.配置对象(自动生成form表单)
*/
type formProp = {success: (values: any) => void;cancel: () => void;okTxt: string;options?: any;
};type FieldType = {username?: string;password?: string;remember?: string;
};
export const useForm = (formProp: formProp) => {const { success, cancel, okTxt } = formProp;const MyForm = () => {const formRef = React.useRef<FormInstance>(null);const onFinish = useCallback((values: any) => {console.log(values);success(values);}, []);const onFinishFailed = useCallback((values: any) => {console.log(values);}, []);const onReset = () => {formRef.current?.resetFields();};return (<Formref={formRef}labelCol={{ span: 8 }}wrapperCol={{ span: 16 }}style={{ maxWidth: 600 }}initialValues={{ remember: true }}autoComplete="off"onFinish={onFinish}onFinishFailed={onFinishFailed}><Form.Item<FieldType>label="Username"name="username"rules={[{ required: true, message: "Please input your username!" }]}><Input /></Form.Item><Form.Item<FieldType>label="Password"name="password"rules={[{ required: true, message: "Please input your password!" }]}><Input.Password /></Form.Item><Form.Item wrapperCol={{ offset: 8, span: 16 }}><Space wrap><Button type="primary" htmlType="submit">{okTxt}</Button><Button danger htmlType="button" onClick={onReset}>重置</Button><Button onClick={cancel}>取消</Button></Space></Form.Item></Form>);};return {MyForm,};
};
使用
//可以传递type来指定类型
const nomalMadal=useModal()
//执行该函数开启弹窗
const show=()=>{nomalMadal.init().then((res) => {console.log("确定", res);}).catch((err) => {console.log("取消", err);});
}
总结
在之后的学习过程中,要多换思路,不必拘谨于一个点,要把思维发散,逻辑可以多种方法实现,还有就是源码的能力,之后要多学一下源码,了解源码的思想还有实现方法,这样才能更好的玩转第三方库,如果只是简单的使用,那一个小白,培训个几个月也能达到使用的程度,要有自己的见解和自己的优势。
相关文章:
react Hook+antd封装一个优雅的弹窗组件
前言 在之前学vue2的时候封装过一个全局的弹窗组件,可以全局任意地方通过this调用,这次大创项目是用react技术栈,看了一下项目需求,突然发现弹窗还是比较多的,主要分为基础的弹窗以及form表单式的弹窗,如果…...

HICP学习--BGP综合小实验
需要完善 一、实验拓扑 二、实验需求 1、R2-7每台路由器均存在一个环回接口用于建立邻居,同时还存在一个环回来代表连接用户的接口;最终这些连接用户的接口网络需要可以和R1/8的环回通讯 2、AS2网段地址172.16.0.0/16 减路由条目数量 三、实验步骤 首先配置IP R…...

grafana中利用变量来添加dashboard详情页地址实现点击跳转
背景 最近弄grafana的dashboard,突然想到各个dashboard之前可以直接跳转到不同详细页面的面板,于是找了找实现方法 实现 以stat 格式的面板为例,显示出各个pod的对应状态, PromQL是(avg(kube_pod_status_phase{phase"Running", namespace!"kube-system"…...
正则表达式练习
正则表达式练习 工具目的代码运行结果 工具 pycharm 目的 https://www.77xsw.cc/fenlei/1_1/:第一页的网址 https://www.77xsw.cc/fenlei/1_2/:第二页的网址 ... https://www.77xsw.cc/fenlei/1_10/:第十页的网址 代码 import requests im…...
leetcode做题笔记73矩阵置零
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 思路一:记录行列值 void setZeroes(int** matrix, int matrixSize, int* matrixColSize){int row[matrixSize],col[*matrixColSize];fo…...

【2.1】Java微服务: Nacos的使用
目录 Nacos介绍 Nacos安装 下载和安装 修改端口 启动 服务注册与发现 导入Nacos管理依赖 导入服务依赖 配置Nacos的服务地址 启动服务,查看已注册的服务 服务分级存储模型 分级存储模型介绍 具体结构 配置实例集群 同集群优先的负载均衡策略 服务权重配置…...

vue安装及环境配置
vue安装及环境配置 1.安装 Node.js 2.配置默认安装目录和缓存日志目录 3.配置环境变量 4.配置淘宝镜像 5.安装vue和脚手架 6.创建并运行项目 1.安装 Node.js Download | Node.js 在这里👆下载的是最新版,如果要安装以前的版本👇&…...

java使用正则表达式时遇到的问题
标准的正则表达式是什么样的 Node.js(JavaScript) 在正则表达式中,斜杠(/)用来表示正则表达式的开始和结束。在JavaScript中,正则表达式可以使用斜杠包裹起来,以表示这是一个正则表达式的字面量。 在Node.js中&…...

Git介绍及常用命令详解
一、Git的概述 Git是一个分布式版本控制工具,通常用来对软件开发过程中的源代码文件进行管理。 Git 会跟踪我们对文件所做的更改,因此我们可以记录已完成的工作,并且可以在需要时恢复到特定或以前的版本。Git 还使多人协作变得更加容易&…...

赛事 | 第25届中国机器人及人工智能大赛全国决赛榜单发布
第25届中国机器人及人工智能大赛成功举办 2023年6月13日至14日,第二十五届中国机器人及人工智能大赛于海南科技职业大学成功举办。大赛由中国人工智能学会主办,共有来自清华大学、哈尔滨工业大学、中国科学技术大学、西安交通大学等500多所高校进入全国…...
JavaScript+Asp.Net MVC5同时下载多个文件
前端同时启动多个下载任务(但是没有做压缩包下载) 前端JavaScript脚本: var idList [1,2,3];//要下载的列表 $.each(idList, function (index, item) {downloadURL("/File/GetPdf?id" item); });var count 0; var downloadUR…...

如何实现前后端分离-----前端笔记
本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论,如有侵权请联系,将源码补充写的更快哦!!!等一会把源码补一下哦! 拿一个项目看…...
Ceph入门到精通-分布式存储产品的测试实践
分布式存储产品的测试实践 在分布式存储产品的测试过程中,测试到底做了些什么事情呢? 一:测试工作内容 需求,设计评审 测试需要参与到每一个过程中 在设计评审的时候就需要知道验收的标准,这是最重要的开始。因为这…...
【java】设计模式——单例模式
单例模式要点: 一个类只需要一个实例化对象;必须自行创建实例;必须自行向整个系统提供这个实例 实现: 只提供私有构造方法;有一个该类的静态私有对象;提供一个静态公有方法用于创建、获取静态私有对象&…...

【编织时空一:探究顺序表与链表的数据之旅】
本章重点 线性表 顺序表 顺序表OJ题 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结…...

Tesseract用OpenCV进行文本检测
我没有混日子,只是辛苦的时候没人看到罢了 一、什么是Tesseract Tesseract是一个开源的OCR(Optical Character Recognition)引擎,OCR是一种技术,它可以识别和解析图像中的文本内容,使计算机能够理解并处理…...
XLua案例学习
下载 xlua 之后把 asset 文件中的全部文件粘贴到项目文件Asset文件下,将tool粘贴到 asset 同级目录下 然后把 HOTFIX_ENABLE 宏打开 之后 编辑 lua 脚本 更改源代码之后先 Generate Code 然后 HotFix inject in Editor 开发过程: 首先开发业务…...

Linux:Shell编程之免交互
目录 绪论 1、here Document免交互 1.1 格式 1.2 cat结合免交互实现重定向输出到指定文件 1.3 变量替换 2、Expect免交互 2.1 三种写法 3、免交互实现普通用户切换root 3.1 send_user 4、接收参数 5、嵌入执行模式 6、ssh远程登录 绪论 免交互:不需要人…...

最强自动化测试框架Playwright(18)- 执行js脚本
page.evaluate() API 可以在网页上下文中运行 JavaScript 函数,并将结果带回 Playwright 环境。 href page.evaluate(() > document.location.href) 如果结果是 Promise 或函数是异步的,则计算将自动等待,直到解析…...

阿里云云主机_ECS云服务器_轻量_GPU_虚拟主机详解
阿里云云主机分为云虚拟主机、云服务器ECS、轻量应用服务器、GPU云服务器、弹性裸金属服务器、专有宿主机、FPGA云服务器、高性能计算E-HPC、无影云电脑等,阿里云百科来详细说下阿里云云主机详解: 目录 阿里云云主机 云服务器ECS 轻量应用服务器 云…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...

Springboot 高校报修与互助平台小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,高校报修与互助平台小程序被用户普遍使用,为…...

Ray框架:分布式AI训练与调参实践
Ray框架:分布式AI训练与调参实践 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 Ray框架:分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...
标注工具核心架构分析——主窗口的图像显示
🏗️ 标注工具核心架构分析 📋 系统概述 主要有两个核心类,采用经典的 Scene-View 架构模式: 🎯 核心类结构 1. AnnotationScene (QGraphicsScene子类) 主要负责标注场景的管理和交互 🔧 关键函数&…...

VSCode 没有添加Windows右键菜单
关键字:VSCode;Windows右键菜单;注册表。 文章目录 前言一、工程环境二、配置流程1.右键文件打开2.右键文件夹打开3.右键空白处打开文件夹 三、测试总结 前言 安装 VSCode 时没有注意,实际使用的时候发现 VSCode 在 Windows 菜单栏…...

电脑定时关机工具推荐
软件介绍 本文介绍一款轻量级的电脑自动关机工具,无需安装,使用简单,可满足定时关机需求。 工具简介 这款关机助手是一款无需安装的小型软件,文件体积仅60KB,下载后可直接运行,无需复杂配置。 使用…...