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
相关产品推荐
相关产品推荐

