我想创建一个 Portal 组件,该组件应该附加到它的容器组件,但不是通过容器的 ID,而是通过它的引用。换句话说,我不想将 document.getElementById('CONTAINER_ID') 作为第二个参数传递给 ReactDOM.createPortal 函数,而是仅依赖于 React.forwardRef 传递的容器的 ref。
有没有一种简单的方法可以实现这一目标?
否则我可能需要先创建一个“附加”到 ref 的 dom 节点,然后将该节点传递给
createPortal 函数作为第二个参数?我想尽可能避免分配 id。这是示例代码(我在 TypeScript 中工作):
export default React.forwardRef<HTMLDivElement, Props>( (Props, ref) =>{
const {state, options, dispatch} = Props
if(!state.open) return null
return ReactDOM.createPortal(
<div
className={css`
height: 140px;
background: white;
overflow-y: scroll;
position: absolute;
width:100%;
`}
>
{options}
</div>,
ref.current // <-- THIS DOESN'T WORK
)
}
)
forwardRef
当父组件需要访问子元素时使用,而不是相反。要将元素传递给子元素,您可以通过 prop 来完成。此外,由于直到第一次渲染后才会填充引用,因此您可能需要渲染父组件两次,一次将容器放在页面上,然后再次将其传递给子组件,以便子组件可以创建门户。
const Parent = () => {
const ref = useRef<HTMLDivElement>(null);
const [element, setElement] = useState<HTMLDivElement | null>(null);
useEffect(() => {
// Force a rerender, so it can be passed to the child.
// If this causes an unwanted flicker, use useLayoutEffect instead
setElement(ref.current);
}, []);
return (
<div ref={ref}>
{element && (
<Child element={element} {/* insert other props here */} />
)}
</div>
)
}
const Child = (props: Props) => {
const { state, options, dispatch, element } = props;
if (!state.open) {
return null;
}
return ReactDOM.createPortal(
<div
className={css`
height: 140px;
background: white;
overflow-y: scroll;
position: absolute;
width: 100%;
`}
>
{options}
</div>,
element
);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)