antd中的Modal,用方法打开弹窗

445 阅读1分钟

使用Modal的时候,需要用visible维护状态。当你的Modal是创建和编辑公用的时候,还得维护一坨数据。想要方便,来试试Modal.show吧

使用案例
const handleClick = () => {
    const { hide } = Modal.show({
      title: '新建',
      content: (
        <div>jsx</div>
      ),
      cancelText: '取消',
      okText: '确认',
      // 这里使用Promise,是考虑到触发onOk不关闭弹窗的情况,比如这里调接口失败了
      // 执行resolve(),弹窗关闭。执行reject,关窗不动
      onOk: () => {
        return new Promise((resolve, reject) => {
          reject();
        })
      },
      onCancel: () => {
        console.log('click cancel')
        hide();
      }
    })
  }
封装代码
import React, { forwardRef } from 'react';
import ReactDOM from 'react-dom';
import { Modal as AntdModal } from 'antd';

const Modal = (props) => {
  const { visible, children, ...rest } = props;

  return (
    <AntdModal
      {...rest}
      visible={visible}
    >
      {
        typeof children === 'object' ? React.Children.map(children, child => React.cloneElement(child)) : children
      }
    </AntdModal>
  )
}

const forwardRefModal = forwardRef(Modal);

export default forwardRefModal;

forwardRefModal.show = (props) => {
  const { title, content, ...rest } = props;
  // 手动创建元素承载Dialog
  let element = document.createElement('div');
  document.body.appendChild(element);
  
  const onClose = () => {
    ReactDOM.render(getModalNode({ visible: false }), element)
  }
  
  const afterClose = () => {
    ReactDOM.unmountComponentAtNode(element);
    element.remove();
    element = null;
    if (props.afterClose && typeof props.afterClose === 'function') {
      props.afterClose();
    }
  }
  
  // 这里代码比较啰嗦,主要判断该函数是不是Promise
  const onOk = () => {
    if (props.onOk && typeof props.onOk === 'function') {
      const maybePromise = props.onOk();
      if (maybePromise instanceof Promise) {
        maybePromise
          .then(() => {
            onClose();
          })
      } else {
        onClose();
      }
      return;
    }
    onClose();
  }
  
  const getModalNode = ({ visible }) => {
    let modalNode = null;
    modalNode = (
      <Modal
        {...rest}
        visible={visible}
        title={title}
        afterClose={afterClose}
        onOk={onOk}
      >
        {content}
      </Modal>
    )
    return modalNode;
  }
  ReactDOM.render(getModalNode({ visible: true }), element)
  return {
    hide: onClose
  }
}