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

React 18中如何通过代码方式创建Modal组件?

React 18 替代 ReactDOM.render 实现动态创建 Modal 的方案

问题背景

在 React 17 中通过调用函数实现了动态创建 Modal 的功能,只需调用函数就能生成新的 Modal 实例,且组件可自行管理状态、支持多实例同时存在。但 React 18 中 ReactDOM.render 被弃用后,原有功能无法正常运行,需要找到能在指定 DOM 元素中渲染简单组件的替代方案。

解决方案

React 18 中可以用 createRoot API 替代 ReactDOM.render,核心思路是为每个动态创建的 Modal 生成独立的 DOM 容器,避免多实例冲突,同时在 Modal 关闭时自动卸载根实例并清理 DOM,防止内存泄漏。

修改后的代码实现

1. 全局容器(index.js)

仅需将原有的 ReactDOM.render 替换为 React 18 的 createRoot 写法,保留 modal-container:

import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.scss'
import App from './App.jsx'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <div id="modal-container"></div>
    <App />
  </React.StrictMode>
)

2. Modal 组件(Modal/Modal.jsx)

新增 onClose 回调,用于在关闭时通知外部执行卸载逻辑:

import { useState } from 'react'
import './Modal.scss'

const Modal = ({ content, onClose }) => {
    const [isOpen, setIsOpen] = useState(true)

    const handleClose = () => {
        setIsOpen(false)
        onClose()
    }

    if (isOpen) {
        return (
            <>
                <div className="modal-background" onClick={handleClose} />
                <div className="modal-content">
                    {content}
                </div>
                <button onClick={handleClose} className="close-button">Close</button>
            </>
        )
    } else return null
}

export default Modal

3. 创建 Modal 的工具函数(Modal/index.js)

使用 createRoot 替代原有的 render,为每个 Modal 创建独立 DOM 容器:

import { createRoot } from "react-dom/client"
import Modal from "./Modal"

const createModal = (content) => {
    // 创建独立的 DOM 元素
    const modalElement = document.createElement('div')
    // 将元素挂载到全局 Modal 容器中
    document.getElementById("modal-container").appendChild(modalElement)

    // 创建 React 根实例并渲染 Modal
    const root = createRoot(modalElement)
    root.render(
        <Modal 
            content={content} 
            onClose={() => {
                // 卸载 React 根实例
                root.unmount()
                // 移除对应的 DOM 元素
                modalElement.remove()
            }} 
        />
    )
}

export default createModal

4. 调用示例(app.jsx)

无需改动,保持原有的便捷调用方式:

<button onClick={() => createModal(<h1>I'm a component inside a modal</h1>)}>Open Modal</button>

说明

  • 每个动态生成的 Modal 都拥有独立的 React 根实例和 DOM 元素,多实例之间互不干扰
  • 关闭 Modal 时会自动完成根实例卸载和 DOM 清理,避免内存泄漏
  • 完全保留了原有的“调用函数即创建 Modal”的便捷性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:36:20