【发布时间】:2020-10-27 13:12:35
【问题描述】:
我正在尝试创建一个弹出对话框,以便在用户单击按钮时显示。为此,我正在使用门户网站。
所以基本上,当用户点击添加按钮时,我希望弹出对话框显示如上图所示。
在弹出组件中,我想用孩子渲染叠加层。当用户点击覆盖 div 时,弹出窗口应该关闭。
我有一些不使用 Portal 就可以工作的东西,如下所示,
下面是我没有使用 Portal 的代码,
function Parent({isDialogOpen, setDialogOpen, setSomething}: Props) {
const [isClicked, setIsClicked] = React.useState(false);
const handleButtonClick = () => {
if (setIsDialogOpen) setIsDialogOpen(!isDialogOpen);
if (setSomething) setSomething(isDialogOpen);
setIsClicked(!isClicked);
};
return (
<button onClick={handleButtonClick}>click</button>
{isDialogOpen && isClicked &&
<Overlay>
<Dialog>
//some divs
</Dialog>
</Overlay>
}
);
}
const Overlay = styled.div`
position: fixed;
padding-top:60px;
bottom: 40px;
top: 0;
left: 0;
right: 0;
backdrop-filter: blur(8px);
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
`;
const Dialog = styled.div`
padding: 16px;
width: 384px;
max-height: calc(100% - 200px);
display: flex;
flex-direction: column;
`;
现在我正在使用下面的门户重写上面,
function Parent({isDialogOpen, setDialogOpen, setSomething}: Props) {
const [isClicked, setIsClicked] = React.useState(false);
const handleButtonClick = () => {
if (setIsDialogOpen) setIsDialogOpen(!isDialogOpen);
if (setSomething) setSomething(isDialogOpen);
setIsClicked(!isClicked);
};
return (
<button onClick={handleButtonClick}>click</button>
{isDialogOpen && isClicked &&
<Popup setSomething={setSomething} setIsDialogOpen={setIsDialogOpen} setIsClicked=
{setIsClicked}>
<Dialog>
//some divs
</Dialog>
</Overlay>
}
);
}
function Popup({setIsClicked, setSomething, setIsDialogOpen, children}: Props) {
return ReactDom.createPortal(
<>
<Overlay
onClick={() => {
if (setIsDialogOpen) setIsDialogOpen(false);
if (setSomething) setSomething(true);
setIsClicked(false);
}}
>
{children}
</Overlay>
</>,
//dont know what to pass here
);
}
基本上如上图所示,我想用对话框渲染叠加层。
现在在弹出组件中,我想创建类名为“popup”的 div,并找到带有类导航栏的 div 元素,并将此 div 弹出窗口附加到导航栏 div
并在 reactDOM.createPortal 中使用弹出类传递这个 div 元素。
我是新手,不知道该怎么做。有人可以帮我解决这个问题吗?
谢谢。
【问题讨论】:
-
这不是您使用门户的方式。您需要将门户安装到现有的 dom 节点中,就像使用
ReactDom.render( targetNode, componentTree )渲染您的应用程序一样。因此,例如,您可以在主应用程序中安装一些元素,例如<div id="popup-dialog" />,因此您可以像ReactDom.createPortal( document.getElementById('popup-dialog'), <MyComponent />);那样渲染成这样,您需要考虑使用门户网站的一件事,就是您要在 dom 中渲染的元素在渲染之前必须在那里。你如何处理这取决于你的实现。 -
好的。那么如何将我上面不使用 Portal 的代码重写为使用 Portal 的代码呢?谢谢
-
由您决定。您是想通过另一个组件控制门户,还是只是您需要在树顶部的一个 dom 节点,您可以根据需要将弹出窗口呈现到其中?如果是后者,您可以在组件第一次渲染时使用回调来创建元素并将其附加到
body,然后渲染到该元素中
标签: javascript reactjs typescript