React写一个 Modal组件

news2024/12/26 18:22:39

吐槽一波

最近公司的项目终于度过了混乱的前期开发,现在开始有了喘息时间可以进行"规范"的处理了。
组件的处理,永远是前端的第一大任务,尤其是在我们的ui库并不怎么可靠的情况下,各个组件的封装都很重要,而Modal作为最独立的组件,就先拿它开刀了。

Modal的ui

首先,我们要创建一个最基本的组件,一个fixed布局的ui布局
在这里插入图片描述

import React from "react";
import "./App.css";function App() {
  return (
    <div className="fixed bottom-0 top-0 isd_modal">
      <div className="isd_modal_container top-50 fixed">
        <div className="isd_modal_header">
          <div>Modal Title</div>
          <div className="icon">x</div>
        </div>
        <div className="isd_modal_body py-0 px-4">Modal content</div>
        <div className="isd_modal_footer">
          <div className="cancel_btn btn h-9">Cancel</div>
          <div className="confirm_btn btn h-9">Ok</div>
        </div>
      </div>
    </div>
  );
}export default App;


由于css样式不是关注的重点,所以只会在最后的地方贴上css。
上面的代码也没啥好讲的,ui也贴出来了。

封装组件

最基本的ui构建完成后,我们需要将它封装成为一个组件,并且将各个参数传进来,最基本的参数无非是title以及content的内容,外加点击ok按钮以及cancel按钮的回调,以及最重要的控制Modal的显隐,下面的例子也会添加这么几个参数。

import { FC } from "react";
import "./index.css";interface ModalComponentProps {
  isVisible: boolean;
  modalTitle: string;
  children: React.ReactNode;
  onOk: () => void;
  onClose: () => void;
}const ModalComponent: FC<ModalComponentProps> = ({
  isVisible,
  children,
  modalTitle,
  onClose,
  onOk,
}) => {
  return isVisible ? (
    <div className="fixed bottom-0 top-0 isd_modal">
      <div className="isd_modal_container top-50 fixed">
        <div className="isd_modal_header">
          <div>{modalTitle}</div>
          <div className="icon" onClick={onClose}>
            x
          </div>
        </div>
        <div className="isd_modal_body py-0 px-4">{children}</div>
        <div className="isd_modal_footer">
          <div className="cancel_btn btn h-9" onClick={onClose}>
            Cancel
          </div>
          <div className="confirm_btn btn h-9" onClick={onOk}>
            Ok
          </div>
        </div>
      </div>
    </div>
  ) : null;
};
export default ModalComponent;

组件接受了从外部传进来的各个参数,并且将其渲染在页面上,如果有一些特殊性的动作,比如会从外部切换显示隐藏,建议对isVisible属性做useEffect的监听。
外部使用该组件的方法如下:

  <ModalComponent
        isVisible={modalVisible}
        modalTitle={"title from App.tsx"}
        children={<div>content from App.tsx</div>}
        onOk={function (): void {
          console.log("onOk from App.tsx");
          setModalVisible(false);
        }}
        onClose={function (): void {
          console.log("onClose from App.tsx");
          setModalVisible(false);
        }}
      />
其中,modalVisible一般会使用useState去存储状态

  const [modalVisible, setModalVisible] = React.useState(false);
做完这些,我们还需要使用createPortal做为我们的点睛之笔,将整个组件挂载在body上,这是必须要做的。

const ModalComponent: FC<ModalComponentProps> = ({
  isVisible,
  children,
  modalTitle,
  onClose,
  onOk,
}) => {
  const renderModal = createPortal(
    <div className="fixed bottom-0 top-0 isd_modal">
      <div className="isd_modal_container top-50 fixed">
        <div className="isd_modal_header">
          <div>{modalTitle}</div>
          <div className="icon" onClick={onClose}>
            x
          </div>
        </div>
        <div className="isd_modal_body py-0 px-4">{children}</div>
        <div className="isd_modal_footer">
          <div className="cancel_btn btn h-9" onClick={onClose}>
            Cancel
          </div>
          <div className="confirm_btn btn h-9" onClick={onOk}>
            Ok
          </div>
        </div>
      </div>
    </div>
,
    document.body
  );
  return isVisible ? renderModal : null;
};

上述代码中,第八行使用了createPortal去将我们的Modal挂载在了body上。
css文件如下:

.bottom-0{
    bottom: 0;
  }
  .top-0{
    top: 0;
  }
  .top-50{
    top: 50%;
  
  }
  .fixed{
    position: fixed;
  }
  .py-0{
    padding: 0;
  }
  .px-4{
    padding-left: 8px;
    padding-right: 8px;
  }
  .isd_modal {
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 10000;
  }
  
  .isd_modal .isd_modal_container {
    background-color: #ffffff;
    border-radius: 8px;
    min-width: 600px;
    max-width: 80vw;
    height: fit-content;
    width: fit-content;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
  }
  .isd_modal .isd_modal_container .isd_modal_header {
    height: 60px;
    padding: 16px;
    font-size: 20px;
    line-height: 28px;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  
  .isd_modal .isd_modal_container .isd_modal_footer {
    height: 68px;
    margin-bottom: 16px;
    padding: 0px 16px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }
  .isd_modal .icon {
    cursor: pointer;
  }
  .isd_modal .isd_modal_footer .btn {
    min-width: 78px;
    padding: 8px 16px;
    width: fit-content;
    font-size: 14px;
    border-radius: 4px;
    line-height: 20px;
    text-align: center;
    cursor: pointer;
  }
  .isd_modal .confirm_btn {
    background-color: #1274a1;
    color: #ffffff;
    border: 1px solid #ffffff;
    margin-left: 16px;
  }
  
  .isd_modal .cancel_btn {
    background-color: #fbfbfb;
    color: #242424;
    border: 1px solid #b8b8b8;
  }
  .isd_modal .icon_close {
    fill: #1b1b1b;
  }
  
组件的全部代码如下:
import { FC } from "react";
import "./index.css";
import { createPortal } from "react-dom";interface ModalComponentProps {
  isVisible: boolean;
  modalTitle: string;
  children: React.ReactNode;
  onOk: () => void;
  onClose: () => void;
}const ModalComponent: FC<ModalComponentProps> = ({
  isVisible,
  children,
  modalTitle,
  onClose,
  onOk,
}) => {
  const renderModal = createPortal(
    <div className="fixed bottom-0 top-0 isd_modal">
      <div className="isd_modal_container top-50 fixed">
        <div className="isd_modal_header">
          <div>{modalTitle}</div>
          <div className="icon" onClick={onClose}>
            x
          </div>
        </div>
        <div className="isd_modal_body py-0 px-4">{children}</div>
        <div className="isd_modal_footer">
          <div className="cancel_btn btn h-9" onClick={onClose}>
            Cancel
          </div>
          <div className="confirm_btn btn h-9" onClick={onOk}>
            Ok
          </div>
        </div>
      </div>
    </div>
,
    document.body
  );
  return isVisible ? renderModal : null;
};
export default ModalComponent;


Modal作为一个最基本而又最独立的组件,是必须要学会如何封装的!
在这里插入图片描述

公众号文章链接

求关注~ 希望能帮到你~​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1828939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python】Python实现解压rar文件

Python实现解压rar文件 零、需求 最近在开发一个填分数的应用&#xff0c;需要用到selenium&#xff0c;那么自然需要用到浏览器&#xff0c;浏览器内置到应用中&#xff0c;但是上传到GitCode的时候被限制了&#xff0c;单个文件大小只能是10M以内。所以只能压缩&#xff0c…

Folx软件安装教程及最新版下载

简介&#xff1a; Folx Pro是一款适合Mac的专业下载工具也是一款BT下载器&#xff0c;Folx中文版有一个支持Retina显示的现代界面&#xff0c;提供独特的系统排序、存储下载内容与预览下载文件。Folx中文官网提供Folx教程、激活码、下载。 安 装 包 获 取 地 址&#xff1a; …

轻松实现H5页面下拉刷新:滑动触发、高度提示与数据刷新全攻略

前段时间在做小程序到H5的迁移&#xff0c;其中小程序中下拉刷新的功能引起了产品的注意。他说到&#xff0c;哎&#xff0c;我们迁移后的H5页面怎么没有下拉刷新&#xff0c;于是乎&#xff0c;我就急忙将这部分的内容给填上。 本来是计划使用成熟的组件库来实现&#xff0c;…

Linux,shell ,gun基本概念和关系

Linux 系统简单架构图 1、命令行界面&#xff08;CLI&#xff09;和图形用户界面 (GUI) 1、图形界面就是我们常用的windows系统这种&#xff0c;打开文件&#xff0c;双击一下。想选择哪个文件&#xff0c;就鼠标移动到哪里选择就行。 2、命令行界面就是下面这种只有黑乎乎的…

iText7画发票PDF——小tips

itext7教程&#xff1a; 1、https://blog.csdn.net/allway2/article/details/124295097 2、https://max.book118.com/html/2017/0720/123235195.shtm 3、https://www.cnblogs.com/fonks/p/15090635.html 4、https://www.cnblogs.com/sky-chen/p/13026203.html 5、官方&#xff…

【猫狗分类】Pytorch VGG16 实现猫狗分类4-开始训练

背景 现在&#xff0c;我们已经完成了&#xff0c;数据集的清洗&#xff0c;标签的制作&#xff0c;也把VGG16的模型建立好了。那接下来&#xff0c;我们应该把数据&#xff0c;放到我们搭建的vgg16的模型里面&#xff0c;让模型针对这些猫和狗的图片&#xff0c;去进行训练&a…

Java并发编程深度解析:构建高并发应用的实践与探究

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;大型分布式系统对并发处理能力的要求越来越高。Java作为企业级应用的主流开发语言&#xff0c;在并发编程方面有着深厚的积累和强大的生态支持。本文将深入探讨Java并发编程的基础知识&#xff0c;高级技巧&#xff0c;以…

c++_0基础_讲解7 练习

这一讲我为大家准备了几道题目&#xff0c;大家试着独自做一下&#xff08;可能来自不同网站&#xff09; 整数大小比较 - 洛谷 题目描述 输入两个整数&#xff0c;比较它们的大小。若 x>yx>y &#xff0c;输出 > &#xff1b;若 xyxy &#xff0c;输出 &#xff…

Java高级技术探索:深入理解JVM内存分区与GC机制

文章目录 引言JVM内存分区概览垃圾回收机制&#xff08;GC&#xff09;GC算法基础常见垃圾回收器ParNew /Serial old 收集器运行示意图 优化实践结语 引言 Java作为一门广泛应用于企业级开发的编程语言&#xff0c;其背后的Java虚拟机&#xff08;JVM&#xff09;扮演着至关重…

UDS——2F服务:输入输出控制

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍输入输出控制服务下的2F服务InputOutputControlByIdentifier,该服务主要在车身域比较常见,比如车窗控制,传感器开关、执行器控制等。 参考文章: 数据传输功能单元——DID参数定义 22服务-ReadDataByIdentifier …

python3GUI--记账助手By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;开发环境三&#xff0e;预览1.登录&注册2.主界面3.新增账单1.当前日期2.选择日期3.添加成功 4.删除账单4.筛选账单5.账单数据汇总1.日账单2.月账单3.年账单 四&#xff0e;设计心得1.项目代码结构2.UI设计概览3.UI设计详细1.登录…

LLVM后端 td文件 tablegen 模式匹配 寄存器 指令集 calling convention

目录 一、寄存器 1.1 寄存器定义 1.2 寄存器分类 二、指令集 2.1 指令集定义 2.2 模式匹配 2.2.1 PatFrags与PatFrag 2.2.2 OutPatFrag 2.2.3 PatLeaf 2.2.4 ImmLeaf 2.2.5 IntImmLeaf和FPImmLeaf 2.2.6 Pat 2.2.7 ComplexPattern 2.3 指令合法化 2.3.1 Promote…

System-Verilog 实现DE2-115 流水灯

文章目录 一、什么是SystemVerilog二、代码实现实现结果 一、什么是SystemVerilog SystemVerilog是一种硬件描述语言(HDL)&#xff0c;它用于设计和验证电子系统&#xff0c;特别是在集成电路(IC)和系统级芯片(SoC)的设计过程中。SystemVerilog是Verilog语言的一个超集&#xf…

存储器的性能指标以及层次化存储器

存储器的性能指标 存储器有三个性能指标&#xff1a;速度、容量和位价&#xff08;每位价格&#xff09; 1.存储速度 &#xff08;1&#xff09;存取时间 想衡量存储速度&#xff0c;最直观的指标就是完成一次存储器读写操作所需要的时间&#xff0c;这叫做存取时间&#x…

如何交叉编译Libsndfile

Libsndfile 是一个用于读取和写入文件的 C 库&#xff0c;它支持多种音频文件格式&#xff0c;包括 WAV、AIFF、FLAC 等。这个库提供了一个简单的 API 来处理音频数据&#xff0c;使得开发者可以在他们的应用程序中轻松地集成音频文件的读写功能。今天介绍一下如何针对x210平台…

C++ 45 之 赋值运算符的重载

#include <iostream> #include <string> #include <cstring> using namespace std;class Students05{ public:int m_age;char* m_name;Students05(){}Students05(const char* name,int age){// 申请堆空间保存m_name;this->m_name new char[strlen(name)…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 部门项目任务分配(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 部门项目任务分配(100分) 🌍 评测功能需要订阅专栏后私信联…

代码随想录——组合总和Ⅱ(Leetcode 40)需要回顾

题目链接 回溯 本题的难点在于&#xff1a;集合&#xff08;数组candidates&#xff09;有重复元素&#xff0c;但还不能有重复的组合。 思想&#xff1a;元素在同一个组合内是可以重复的&#xff0c;怎么重复都没事&#xff0c;但两个组合不能相同。所以要去重的是同一树…

HAL库开发--SPI的配置方式和读写操作

知不足而奋进 望远山而前行 目录 文章目录 前言 目标 内容 需求 SPI配置 SPI编码 OLED驱动拷贝 OLED的GPIO初始化修改 实现SPI的读写 总结 前言 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种常见的串行通信协议&#xff0c;在嵌入式系统中被广泛…

技巧解析,如何向Kimi提问才能写出更好的论文?

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 今天为大家整理、分享的Kimi提问技巧&#xff0c;将对论文写作的各个阶段提供帮助&#xff0c;可以以此来辅助学术论文撰写。 在此之前&#xff0c;先为大家科普一个概念——信息熵&am…