import React from "react"; import ReactDOM from "react-dom"; import { createPortal } from "react-dom"; import { isBrowser } from "../Utils/utils"; import styles from "./Modal.less"; export interface ModalProps { visible: boolean; onCancel: (e: any) => void; container?: HTMLElement; } export class Modal extends React.PureComponent { static hasShowWarning = false; render() { if (!isBrowser()) return null; // 服务端无需渲染下列代码,渲染也会出错 const DEFAULT_CONTAINER: HTMLElement | null = document.getElementById( "container" ); const { children, visible, onCancel, container } = this.props; let finalMountContainer: HTMLElement; if (!container) { if (!DEFAULT_CONTAINER) { if (!Modal.hasShowWarning) { Modal.hasShowWarning = true; } finalMountContainer = document.body; } else { if (!Modal.hasShowWarning) { Modal.hasShowWarning = true; } finalMountContainer = DEFAULT_CONTAINER; } } else { finalMountContainer = container; } return ( visible && createPortal(
{children}
, finalMountContainer ) ); } } export interface ModalCMDOptions { children: any; container?: HTMLElement; options?: { mask?: true; }; } export interface ModalCMDRecord { modalInstance: HTMLElement; } export class ModalCMD { static currentModal: ModalCMDRecord[] = []; constructor() { ModalCMD.currentModal = []; } private static recordModal(record: ModalCMDRecord) { ModalCMD.currentModal.push(record); } private static delModal() { return ModalCMD.currentModal.pop(); } static show({ children, container }: ModalCMDOptions) { const modalInstance = document.createElement("div"); let targetMountDom = container ? container : document.body; targetMountDom.appendChild(modalInstance); ReactDOM.render( <>
{ ModalCMD.hide(ModalCMD.currentModal.length); }} />
{children}
, modalInstance ); this.recordModal({ modalInstance }); } static hide(targetId?: string | number) { const popModalRecord: ModalCMDRecord | undefined = this.delModal(); if (popModalRecord && popModalRecord.modalInstance) { ReactDOM.unmountComponentAtNode(popModalRecord.modalInstance); const { parentNode } = popModalRecord.modalInstance; parentNode && parentNode.removeChild(popModalRecord.modalInstance); } } } export default Modal;