reactjs - 通过 Ref 创建 React Portal
问题描述
我想创建一个应该附加到它的容器组件的 Portal 组件,但不是通过容器的 ID 而是通过它的 ref。换句话说,我不想将 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
当父组件需要访问子元素时使用,而不是相反。要将元素向下传递给孩子,您将通过道具来完成。此外,由于在第一次渲染之后才会填充 refs,因此您可能需要渲染父组件两次,一次将容器放在页面上,然后再次将其传递给子组件,以便子组件可以创建门户。
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
);
}
推荐阅读
- angular - 如何在角度材料ui中的mat-menu内放置下拉菜单
- python - 如何从这个压缩的 PDF/A 中提取文本?
- python - 如何搜索二维列表并打印位置(x,y)
- java - 如何区分本地wifi网络android游戏中的用户
- raspberry-pi - 通过树莓派 4 访问气流网络
- python - Gmail API 无法获取电子邮件数据
- swift - RealityKit 多人会话 - 对象同步问题
- spring-security - JWT 于 2020-05-13T07:50:39Z 到期。当前时间:2020-05-16T21:29:41Z。正如日志错误所说,我的 jwt 到期后出现此错误
- mysql - go-testfixtures fixtures.Load() 返回校验和错误
- oracle - 如何在内部联接中添加大小写