(React) 将内部React节点挂载到外部: Portal
目的: 想把<Modal /> 深层嵌套React组件中的一个小节点,可以挂载到 #modal-root 上。
方法: 用到了Portal, 它是React的内置功能,无需引入其他库, 直接使用。
步骤:
先封装一个简单的Portal组件
import * as React from 'react'; interface PortalProps { children: React.ReactNode; containerId: string; // 挂载的目标容器 ID } const Portal: React.FC<PortalProps> = ({ children, containerId }) => { const [container, setContainer] = React.useState<HTMLElement | null>(null); React.useEffect(() => { const el = document.getElementById(containerId); if (el) { setContainer(el); } }, [containerId]); if (!container) return null; return ReactDOM.createPortal(children, container); }; export default Portal;
在自己的React组件中使用:
// ... import Portal from './Portal'; // 替换为你实际的路径 render(): React.ReactNode { return ( <div> {/* ... 已有 render 内容 */} {/* 使用 Portal 将部分节点挂载到外部 DOM id为parent_id_666的dom里 */} <Portal containerId="modal-root"> <div className="demo"> 这是自己的小节点内容 </div> </Portal> </div> ); }
总结Portal :
1. 脱离当前组件结构渲染
允许将组件渲染到 任意 DOM 节点,而不受当前组件层级限制。
特别适用于需要挂载到页面其他位置的内容(如弹窗、浮层、提示框等)
2. 样式隔离与布局自由
渲染后的内容不受父组件 CSS 样式影响(如 overflow:hidden),避免布局错乱。
可以更自由地控制元素在页面中的实际位置。
3. 保持 React 组件树逻辑一致性
尽管内容被挂载到了别的地方,但它仍然是 React 组件树的一部分。
状态、props、事件冒泡等机制依然正常工作。
4. 解决 z-index 层级问题
常用于弹窗、菜单、tooltip 等需要高 z-index 的场景。
避免因为父容器的 overflow 或 z-index 设置导致遮挡问题。
5. 提升用户体验
更好地控制 DOM 插入顺序和位置,有助于实现复杂的 UI 动画或交互效果。如:全屏遮罩、浮动按钮、全局通知等。