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

React Portal创建Modal不显示,请求排查代码错误或失误

React Portal Modal无法显示问题排查

我创建了一个用于展示Modal的Portal,但该组件完全无法显示。以下是编写的包含createPortal的Modal组件代码以及index.html代码,请问是代码存在错误还是失误?

Modal组件代码

import React from "react"
import ReactDOM from "react-dom"


const ModalUI = (props) => {
   return (
      <div>
          <h1>hello world </h1>
      </div>
   )
 }


const Modal = (props) => {
   return (
      <div>
           {ReactDOM.createPortal(<ModalUI>{props.children}</ModalUI>, document.getElementById("overlay"))}
      </div>
  )
}
export default Modal;

index.html代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="theme-color" content="#000000" />
  <meta name="description" content="Web site created using create-react-app" />
  <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
  <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
  <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
  <title>React App</title>
</head>

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="overlay"></div>
  <div id="root"></div>
  <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
</body>
</html>

问题分析与解决方案

1. 核心失误:Modal组件未被渲染

最可能的原因是你没有在父组件(比如App.js)中导入并渲染Modal组件。Portal的内容只有当Modal组件被React渲染时,才会被注入到overlay容器中。

修复方式:在App组件中添加Modal的渲染代码:

import Modal from './Modal';

function App() {
  return (
    <div className="App">
      <Modal />
    </div>
  );
}

export default App;

2. 可选优化:确保容器元素存在

虽然你的index.html中已经定义了overlay容器,但可以在Modal组件中添加空值检查,避免DOM元素不存在时的错误:

const Modal = (props) => {
  const overlayEl = document.getElementById("overlay");
  // 如果容器不存在,返回null避免报错
  if (!overlayEl) return null;
  
  return ReactDOM.createPortal(
    <ModalUI>{props.children}</ModalUI>, 
    overlayEl
  );
}

3. 完善ModalUI组件:渲染子内容

当前ModalUI组件没有处理传入的children,如果需要向Modal中传递自定义内容,需要补充渲染逻辑:

const ModalUI = (props) => {
   return (
      <div>
          <h1>hello world </h1>
          {props.children} {/* 渲染传入的子组件/内容 */}
      </div>
   )
 }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:37:14