You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何通过函数调用渲染组件 实现类似Antd Modal.info的能力

命令式调用Modal组件实现方案

核心实现原理

这类不需要提前写JSX、直接调用方法就能渲染的组件,核心逻辑是手动创建独立DOM容器 + 直接调用React渲染API挂载组件,完全不需要在业务组件内维护visible状态,也不需要预留组件渲染位置,所有渲染、销毁逻辑都封装在静态方法内部。


完整实现步骤

1. 编写基础受控Modal组件

先实现一个普通的受控Modal组件,接收显示状态、文案、回调等基础props:

// MyModal.tsx
import { createRoot } from 'react-dom/client';
import type { ReactNode } from 'react';

// 基础Modal接收的props类型
interface BaseModalProps {
  visible: boolean;
  title: string;
  content: ReactNode;
  onOk?: () => void;
  onCancel?: () => void;
}

const BaseModal = (props: BaseModalProps) => {
  const { visible, title, content, onOk, onCancel } = props;
  if (!visible) return null;

  const handleOk = () => {
    onOk?.();
    onCancel?.(); // 点击确定后默认触发关闭逻辑
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
      <div className="bg-white rounded-lg w-[480px] p-6">
        <h3 className="text-xl font-bold mb-4">{title}</h3>
        <div className="mb-6 min-h-[40px]">{content}</div>
        <div className="flex justify-end gap-3">
          <button onClick={onCancel} className="px-4 py-2 border rounded hover:bg-gray-50">取消</button>
          <button onClick={handleOk} className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">确定</button>
        </div>
      </div>
    </div>
  );
};

2. 封装静态命令式调用方法

在同一个文件内,对外导出封装好的MyModal对象,挂载info等静态方法:

// 调用方法时传入的配置类型
interface ModalConfig {
  title: string;
  content: ReactNode;
  onOk?: () => void;
}

const MyModal = {
  info: (config: ModalConfig) => {
    // 1. 创建临时DOM容器,插入到body下
    const container = document.createElement('div');
    document.body.appendChild(container);
    const root = createRoot(container);

    // 2. 封装销毁逻辑:卸载组件 + 移除临时容器
    const destroy = () => {
      root.unmount();
      document.body.removeChild(container);
    };

    // 3. 把基础Modal组件渲染到临时容器中
    root.render(
      <BaseModal
        visible={true}
        title={config.title}
        content={config.content}
        onOk={config.onOk}
        onCancel={destroy}
      />
    );
  },
  // 可按需扩展warning、success、error等方法,仅需调整BaseModal的样式即可
};

export default MyModal;

3. 业务侧使用

和Ant Design的Modal调用方式完全一致:

// 业务组件内调用
import MyModal from './MyModal';

const Item = (props: ItemProps) => {
  const { itemGroup, items } = props;

  const showInfo = () => {
    MyModal.info({
      title: '这是一条通知消息',
      content: (
        <div>
          <p>some messages...some messages...</p>
          <p>some messages...some messages...</p>
        </div>
      ),
      onOk() {
        console.log('点击了确定按钮');
      },
    });
  };

  return (
    <div className="py-6">
      <div
        onClick={showInfo}
        className="cursor-pointer py-6 px-6 text-3xl font-heading font-bold bg-primary text-white"
      >
        <p>{itemGroup.text}</p>
      </div>
      {/* 其余业务逻辑省略 */}
    </div>
  );
};

兼容React17及更早版本

如果使用React17或更低版本,替换createRoot相关逻辑为旧版渲染API即可:

import ReactDOM from 'react-dom';

// 静态方法内的渲染销毁逻辑替换为:
const destroy = () => {
  ReactDOM.unmountComponentAtNode(container);
  document.body.removeChild(container);
};
ReactDOM.render(
  <BaseModal
    visible={true}
    title={config.title}
    content={config.content}
    onOk={config.onOk}
    onCancel={destroy}
  />,
  container
);

内容的提问来源于stack exchange,提问作者bitsmyth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:00:03