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

React Portal生产环境报Target Container is not a DOM element错误求助

问题:生产构建中React Portal报"target container is not a DOM element"错误(开发环境正常)

在生产构建版本中使用React Portal时遇到#200错误“target container is not a DOM element”,但开发环境下无此问题。已确认index.js和modal.js中root与portal的ID书写正确,相关代码如下:

Modal组件代码

import ReactDOM from 'react-dom'
import React from 'react'

const Modal_Styles={
  backgroundColor:'#FFF',
  position:'fixed',
  top:'50%',
  left:'50%',
  right:'10%',
  bottom:'10%',
  padding:50,
  textAlign:'justify',
  transform:'translate(-50%,-50%)',
  borderRadius:'12px',
  zIndex:1000
}
const Overlay_Styles={
  position:'fixed',
  left:0,
  top:0,
  right:0,
  bottom:0,
  backgroundColor:'rgba(0,0,0,0.3)',
  zIndex:1000,
}

export default function Modal({open,children,onClose}) {
   if(!open){return null}
  
  return ReactDOM.createPortal(
    <>
    <div style={Overlay_Styles}>
    <div style={Modal_Styles}>
    {children} 
    <button className='mbutton' onClick={onClose}>x</button>
    </div>
    </div>
    </>,
    document.getElementById('portal')
  )
}

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="C"
    />
    
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <div id="portal"></div>
  </body>
</html>
解决建议
  • 动态获取DOM元素并增加兜底判断:生产环境打包后的代码加载顺序可能和开发环境存在差异,组件初始化时直接调用document.getElementById('portal')可能找不到元素。修改Modal组件,在渲染前动态获取元素并判断:
export default function Modal({open,children,onClose}) {
   if(!open){return null}

  const portalElement = document.getElementById('portal');
  if (!portalElement) return null;
  
  return ReactDOM.createPortal(
    <>
    <div style={Overlay_Styles}>
    <div style={Modal_Styles}>
    {children} 
    <button className='mbutton' onClick={onClose}>x</button>
    </div>
    </div>
    </>,
    portalElement
  )
}
  • 验证生产环境HTML结构:打开生产环境页面,右键查看源代码,确认<div id="portal"></div>是否确实存在于<div id="root"></div>之后,避免打包过程中该元素被意外移除。

  • 用useEffect确保DOM加载完成:借助React的useEffect钩子,在组件挂载后再检查DOM元素是否存在,确保渲染Portal时DOM已完全加载:

import React, { useEffect, useState } from 'react';

export default function Modal({open,children,onClose}) {
  const [portalReady, setPortalReady] = useState(false);

  useEffect(() => {
    if (document.getElementById('portal')) {
      setPortalReady(true);
    }
  }, []);

   if(!open || !portalReady){return null}
  
  return ReactDOM.createPortal(
    <>
    <div style={Overlay_Styles}>
    <div style={Modal_Styles}>
    {children} 
    <button className='mbutton' onClick={onClose}>x</button>
    </div>
    </div>
    </>,
    document.getElementById('portal')
  )
}
  • 检查打包工具配置:如果使用Create React App,确认是否有自定义HTML模板配置导致portal元素丢失;如果是Vite等其他工具,检查HTML插件配置,确保模板中的元素被正确保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:00:58