《React HOC》异步引入定制化的Antd Modal组件

《React HOC》异步引入定制化的Antd Modal组件

使用场景

点击按钮时(或者其他触发时机),异步加载你的Modal组件,可以实现将Modal组件逻辑与主页面逻辑分开维护。

实现

以Antd的Modal为例。

withShowModal.jsx

核心逻辑

// import { ModalProps, Modal } from 'antd';
import React from 'react';
import {
  createPortal,
  render as reactRender,
  unmountComponentAtNode as reactUnmount,
} from 'react-dom';

export function withShowModal(Element) {
  function InnerElement(props) {
    return <Element {...props} />;
  }

  function show(config, targetDom) {
    const container = targetDom || document.getElementById('root') || document.body;
    const renderDom = document.createDocumentFragment();

    function render(props) {
      // reactRender(<InnerElement {...props} />, container);
      reactRender(createPortal(<InnerElement {...props} />, container), renderDom);
    }

    function destroy() {
      reactUnmount(renderDom);
    }

    const currentConfig = {
      ...config,
      open: true,
      onCancel: () => {
        render({ open: false, afterClose: destroy });
      },
      onOk: async (params) => {
        const r = typeof config.onOk === 'function' ? config.onOk(params) : undefined;
        render({ open: false, afterClose: destroy });
        return r;
      },
    };

    render(currentConfig);

    return {
      destroy,
    };
  }

  InnerElement.show = show;

  return InnerElement;
}

Modal组件文件

CreateOrderModal.jsx为例

import { withShowModal } from '../hoc/withShowModal';
import { Form, Modal, Select, InputNumber, message } from 'antd';
import { useEffect, useState, useMemo } from 'react';

const requiredRule = [
  {
    required: true,
    message: '字段不能为空',
  },
];

function ModalApp(props) {
  const { onSuccess, ...rest } = props;
  const [form] = Form.useForm();

  const [loading, setLoading] = useState(false);
  const handleOk = async () => {
    console.log('点击了ok');
    setLoading(true);
    try {
      const vals = await form.validateFields();
      message.info('正在创建订单');
      console.log('vals: ', vals);

      const res = await xxx()
      if (res.status) {
        message.success('创建成功');
        onSuccess?.();
      }
    } catch (e) {
      console.log(e);
      message.warning('创建失败');
    } finally {
      setLoading(false);
    }
  };

  const [formData, setFormData] = useState({});

  const handleValsChange = (changeVal, allVal) => {
    setFormData(allVal);
  };

  return (
    <Modal
      width={600}
      centered
      destroyOnClose
      maskClosable={false}
      {...rest}
      onOk={handleOk}
      okText='确定'
      cancelText='取消'
      okButtonProps={{
        loading: loading,
      }}
    >
      <Form
        onValuesChange={handleValsChange}
        name='createOrderForm'
        form={form}
        labelCol={{
          span: 8,
        }}
        wrapperCol={{
          span: 16,
        }}
        style={{
          maxWidth: 600,
        }}
        initialValues={{}}
        autoComplete='off'
      >
        <Form.Item
          label='交易方式'
          name='tradeType'
          rules={requiredRule}
        >
          <Select
            className='w-full'
            options={[]}
          />
        </Form.Item>
      </Form>
    </Modal>
  );
}

export default withShowModal(ModalApp);

主页面调用
import { useRef } from 'react';
import { Button } from 'antd';

const Operation = () => {

  const handleOrderCreate = async () => {
    const { default: CreateOrderModal } = await import('@/components/CreateOrderModal');
    const { destroy } = CreateOrderModal.show({
      title: '创建订单',
      onSuccess: () => {
        destroy();
      },
      
      // 其它想要传给Modal的property
    });
  };

  return (
    <div>
      <Button onClick={handleOrderCreate}>创建订单</Button>
    </div>
  );
};

export default Operation;

至此全部搞定

相关推荐

  1. 《React HOC》异步引入定制Antd Modal

    2024-03-15 10:08:08       48 阅读
  2. vue

    2024-03-15 10:08:08       50 阅读
  3. uniapp如何引入uview

    2024-03-15 10:08:08       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-15 10:08:08       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-15 10:08:08       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-15 10:08:08       82 阅读
  4. Python语言-面向对象

    2024-03-15 10:08:08       91 阅读

热门阅读

  1. 【C#】【SAP2000】OAPI文档案例详解

    2024-03-15 10:08:08       38 阅读
  2. C#十大排序总结

    2024-03-15 10:08:08       43 阅读
  3. PaddleOCR识别框架解读[14] OCR数据集

    2024-03-15 10:08:08       46 阅读
  4. Oracle数据库 shared pool

    2024-03-15 10:08:08       38 阅读
  5. Kotlin 中的数据类

    2024-03-15 10:08:08       37 阅读
  6. CSS中两栏布局的实现

    2024-03-15 10:08:08       47 阅读