基于React实现:弹窗组件与Promise的有机结合

背景

弹窗在现代应用中是最为常见的一种展示信息的形式,二次确认弹窗是其中最为经典的一种。当我们在React,Vue这种数据驱动视图的前端框架中渲染弹窗基本是固定的使用形式。

使用方式:创建新的弹窗组件,在需要弹窗的地方引用并且需要在外层维护弹窗组件的显示/隐藏状态。

这只是庞大项目中一处需要弹窗的地方,如果项目中存在N个需要弹窗的场景,我们都需要将上述步骤重复一次。这会让我们的项目组件变得臃肿冗余。这也是前端开发者比较头疼且常见的问题。那么我们有没有办法解决这种问题呢?

思考

在最近的一次需求中,我尝试去解决这个问题。首先对于二次确认弹窗这种只有在执行某些动作的时候才需要进行展示,其他时间我们应该忽视它的存在。很明显根据传统的做法我们至少需要维护一个组件实例以及一个状态。

是否可以实现只有在执行具体的动作时才调用二次确认弹窗相关的代码呢?就比如命令式调用方法去渲染组件,可以通过ReactDOM.render实现的这种效果。

接着尝试思考第二个问题,对于二次确认弹窗的交互,其实本质上我们只关心用户点击的取消还是确认。对于这种状态二选一的问题,我脑海里面浮现出熟悉的Promise。

于是,我尝试将二次确认弹窗与Promise进行有机结合,实现出命令式二次确认弹窗。当然这种思路可以运用到其他任何类似的场景。

在线演示Live Demo

事实胜于雄辩,这是下方代码实现的真实效果,感兴趣的同学可自行访问看看效果。

Reconfirm Modal DEMO - FE Component Training

代码实现

普通方式实现

  1. 先通过通用方式实现二次确认弹窗

    import { ReactNode } from "react";
    import { Button } from "antd";
    import "./index.css";interface ModalOption {title: ReactNode;content: ReactNode;okText?: string;cancelText?: string;
    }interface ReconfirmModalProps {onConfirm: () => void;onClose: () => void;options: ModalOption;
    }function ReconfirmModal(props: ReconfirmModalProps) {const { onConfirm, onClose, options } = props;const { title, content, okText, cancelText } = options;return (<div className="reconfirm-modal" style={{ zIndex: 10001 }}><div className="reconfirm-modal-body" style={{ width: 400 }}><p className="reconfirm-modal-title">{title}</p><p className="reconfirm-modal-content">{content}</p><div className="reconfirm-modal-footer"><Button size="large" onClick={onClose} block>{cancelText || "取消"}</Button><Button type="primary" size="large" block onClick={onConfirm}>{okText || "确认"}</Button></div></div></div>);
    }
    
  2. 引用二次确认弹窗,进行简单交互

    export default function ReconfirmModalPage() {const [visible, setVisible] = useState(false);return (<div><Button danger onClick={() => setVisible(true)}>删除</Button>{visible && (<ReconfirmModalonConfirm={() => {setVisible(false);alert("点击了确认按钮");}}onClose={() => {setVisible(false);alert("点击了取消按钮");}}options={{ title: "删除提示", content: "确认删除吗?" }}/>)}</div>);
    }
    
  3. 看看展示效果

    二次确认弹窗演示图

有机结合Promise

我们需要梳理清晰我们的目的,然后再动手进行实现,通过理论指导实践。

首先创建一个方法,调用这个方法时唤醒二次确认弹窗,同时这个方法需要返回二次确认弹窗的交互结果。

通过ReactDOM.render方法将弹窗组件挂在到新创建的root节点上,将Promise的resolve方法传递给弹窗组件的两个按钮事件,此时用户点击按钮时即触发resove方法,Promise状态就从pending状态转移到fulfilled状态。

调用该方法的宿主方法即可得到用户点击二次确认弹窗的点击结果,我们的目的也就达到了。

export const openReconfirmModal = (options: ModalOption) => {return new Promise((resolve) => {const root = document.createElement('div')document.body.appendChild(root)// 移除react组件和DOM节点const removeModal = () => {ReactDOM.unmountComponentAtNode(root)document.body.removeChild(root)}// 点击取消按钮const onClose = () => {removeModal()resolve(false)}// 点击确认按钮const onConfirm = () => {removeModal()resolve(true)}ReactDOM.render(createElement(ReconfirmModal, { onClose, onConfirm, options }), root)})
}

调用二次确认弹窗方法

function ReconfirmModalPage() {const handlePromseReconfirm = async () => {// !!! **直接这么调用就完事儿,简单直接**const res = await openReconfirmModal({title: "删除提示",content: "确认删除吗?",});if (res) {alert("点击了确认按钮");} else {alert("点击了取消按钮");}};return (<Button danger type="primary" onClick={handlePromseReconfirm}>Promise模式删除</Button>);
}

缺点分析

因为我们是通过ReactDOM.render方法渲染的弹窗,这就意味着弹窗组件跟主应用App的状态是隔离的,如果弹窗中用到Redux这种需要上下文Provider能力的工具,就需要在弹窗组件中也初始化一次。但是对于像二次确认弹窗这种简单的纯展示的组件,结合Promise的方式是完全可行的。

总结

日常开发工作中总有一些能够优化的步骤和流程,我们能够多思考一下,转变思路,就能够让我们的代码更加赏心悦目。

原文链接

https://www.levenx.com/article/the-organic-combination-of-pop-up-components-and-promise

个人博客网站,记录更多更全面的内容,

“当你点赞的时候,触碰的不是冰冷的按钮,而是作者那颗感恩的心。”

——鲁迅《非我所言》

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IntelliJ IDEA 2023.2.1 Android开发变化

IntelliJ IDEA 2023.2.1之前的版本&#xff0c;Empty Activity是指Empty View Activity&#xff0c;而现在Empty Activity是指Empty Compose Activity&#xff0c;另外多了一个Empty View Activity的选项 这表明官方推荐使用Compose这种声明式的编程方式来描述UI&#xff0c;命…

FPGA实现电机转速PID控制

通过纯RTL实现电机转速PID控制&#xff0c;包括电机编码器值读取&#xff0c;电机速度、正反转控制&#xff0c;PID算法&#xff0c;卡尔曼滤波&#xff0c;最终实现对电机速度进行控制&#xff0c;使其能够渐近设定的编码器目标值。 一、设计思路 前面通过SOPC之NIOS Ⅱ实现电…

SourceTree安装教程

PS&#xff1a;SourceTree是一款流行的免费Git和Mercurial版本控制工具&#xff0c;由Atlassian开发和维护。它提供了一个直观且功能强大的图形用户界面&#xff0c;方便开发人员管理和浏览代码仓库 说白了&#xff0c;他就是一个可视化的git界面&#xff0c;还是非常好用的&am…

React原理 - React Reconciliation-上

目录 扩展学习资料 React Reconciliation Stack Reconciler【15版本、栈协调】 Stack Reconciler-事务性 事务性带来的弊端&#xff1a; 扩展学习资料 名称 链接 备注 官方文档 Reconciliation – React 英文 stack reconciler Implementation Notes – React 英文…

Java“牵手”京东商品评论数据接口方法,京东商品评论接口,京东商品评价接口,行业数据监测,京东API实现批量商品评论内容数据抓取示例

京东平台商品评论数据接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取京东商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片、评论内容、评论日期、评论图片、追评内容等详细信息 。 获取商品评论接口API是一种用于获取…

QT多线程

1.QT4.7以前的版本-----线程处理方式 1. 出现的警告 直接使用从UI—>转到槽&#xff0c;就会出现警告 2. 出现的错误 error: invalid operands of types QTimer* and void (QTimer::*)(QTimer::QPrivateSignal) to binary operator& 错误:无效的操作数类型’QTimer…

Docker-安装(Linux,Windows)

目录 前言安装版本Docker版本说明前提条件Linux安装使用YUM源部署获取阿里云开源镜像站YUM源文件安装Docker-ce配置Docker Daemon启动文件启动Docker服务并查看已安装版本 使用二进制文件部署 Windows安装实现原理安装步骤基本使用 参考说明 前言 本文主要说明Docker及其相关组…

Docker的基本组成和安装

Docker的基本组成 镜像&#xff08;image&#xff09;&#xff1a; docker镜像就好比是一个模板&#xff0c;可以通过这个模板来创建容器服务&#xff0c;tomcat镜像 > run > tomcat01容器&#xff08;提供服务&#xff09; 通过这个镜像可以创建多个容器&#xff08;最…

uniapp - 倒计时组件-优化循环时间倒计时

使用定时器的规避方法 为了避免定时器误差导致倒计时计算错误&#xff0c;可以采用一些规避方法&#xff0c;比如将倒计时被中断时的剩余时间记录下来&#xff0c;重新开启定时器时再将这个剩余时间加到新的计算中。同时&#xff0c;为了避免定时器延迟&#xff0c;可以在每次执…

【腾讯云 Cloud Studio 实战训练营】使用python爬虫和数据可视化对比“泸州老窖和五粮液4年内股票变化”

Cloud Studio 简介 Cloud Studio是腾讯云发布的云端开发者工具&#xff0c;支持开发者利用Web IDE&#xff08;集成开发环境&#xff09;&#xff0c;实现远程协作开发和应用部署。 现在的Cloud Studio已经全面支持Java Spring Boot、Python、Node.js等多种开发模板示例库&am…

docker常用中间件安装

文章目录 1、前言2、中间件安装2.1、mysql2.2、gitlab容器2.3、nacos2.4、redis2.5、xxljob2.6、zipkin2.7、sentinel2.8、seata2.8.1、获取镜像2.8.2、运行容器并获取配置 2.9、rockerMQ2.9.1、rockerMQ-namesrv2.9.2、rockerMQ-broker2.9.3、rockerMQ-console 2.10、jenkins2…

软考(1)-面向对象的概念

目录 一. 软考基本信息 1. 软考时间&#xff1a; 2. 软考科目&#xff1a; 3.专业知识介绍 -- 综合知识考点分布 4. 专业介绍 -- 软件设计考点分布 二. 面向对象概念 1. 封装 考点一&#xff1a;对象 考点二&#xff1a;封装private 2. 继承 考点三&#xff1a;类 考…