React中如何将子组件挂载在父组件外且仍位于现有DOM树内?
你对Portals的理解存在小偏差:Portals不会把组件挂载到整个页面DOM树之外,只是支持将组件渲染到当前React组件对应的DOM节点层级之外的任意合法DOM节点上,只要目标节点在页面DOM树中就可以,完全符合你的需求。
实现方案
方案1:使用Portals实现(推荐,保留组件上下文关联)
这个方案可以保证<Child_2>的props、React上下文、事件冒泡逻辑和直接写在
- 首先在Page组件中声明挂载<Child_2>的目标容器,通过ref传递给
:
import { useRef } from 'react'; import Parent from './Parent'; const Page = () => { // 存储<Child_2>挂载目标的DOM节点引用 const child2MountRef = useRef(null); return ( <> {/* 你指定的<Child_2>渲染位置 */} <div ref={child2MountRef} /> {/* 将挂载目标传递给Parent组件 */} <Parent child2MountTarget={child2MountRef} /> </> ); };
- 在Parent组件中用
createPortal将<Child_2>挂载到传入的目标节点:
import { createPortal } from 'react-dom'; import Child_1 from './Child_1'; import Child_2 from './Child_2'; const Parent = ({ child2MountTarget }) => { return ( <> <Child_1 /> {/* 目标DOM节点加载完成后,将Child_2渲染到目标位置 */} {child2MountTarget?.current && createPortal(<Child_2 />, child2MountTarget.current)} </> ); };
方案2:插槽传值实现(轻量,适合无上下文依赖场景)
如果<Child_2>不需要访问
- 在
组件中返回<Child_2>但不直接渲染:
import Child_1 from './Child_1'; import Child_2 from './Child_2'; const Parent = () => { return [ <Child_1 key="child1" />, <Child_2 key="child2" /> ]; };
- 在
组件中拆分渲染 返回的内容:
import Parent from './Parent'; const Page = () => { const parentChildren = <Parent />; return ( <> {/* 先渲染Child_2 */} {parentChildren[1]} {/* 再渲染Child_1和Parent其他内容 */} {parentChildren[0]} </> ); };
内容的提问来源于stack exchange,提问作者Gregory Kafanov
相关产品推荐
相关产品推荐

