【发布时间】:2020-08-13 08:44:07
【问题描述】:
我想通过单击使用 TypeScript 和 React 的按钮来关闭对话框。
我想做的事:
在单击 [click me] 按钮时,isDialogOpen 状态设置为 true,如果 isDialogOpen 为 true,则会显示对话框。
如果单击此 [单击我] 按钮或用户单击对话框外的任何位置,则该对话框应关闭。
下面是我的代码:
function Parent() {
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
return (
<button onClick={() => setIsDialogOpen(!isDialogOpen)}> click me </button> //on clicking this
//button should open the dialog. if dialog open
//and clicking this button again should close the dialog
{isDialogOpen &&
<Dialog setIsDialogOpen={setIsDialogOpen}/>
}
);
}
function Dialog({setIsDialogOpen}: Props) {
const dialogRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const handleClickOutsideDialog = (event: any) => {
if (
dialogRef && dialogRef.current &&
!dialogRef.current.contains(event.target)
) {
setIsDialogOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutsideDialog);
return () => {
document.removeEventListener('mousedown', handleClickOutsideDialog);
};
}, [setIsDialogOpen, dialogRef]);
return (
<Wrapper ref={dialogRef}>
<Title> title </Title>
<Description> some big description </Description>
</Wrapper>
);
}
它工作正常。但问题是一旦打开对话框然后单击单击我按钮....对话框消失并立即打开。
如果之前打开了对话框,我希望当用户单击单击我按钮时对话框会关闭。
我不知道问题出在哪里。有人可以帮我解决这个问题吗?谢谢。
编辑
下面是我再次尝试添加一个 ref 到按钮单击我的内容。并将其传递给对话框组件以检查 useeffect 方法。
function Parent() {
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
const buttonRef = React.useRef<HTMLDivElement>(null);
const handleClick = () => {
if (!isDialogOpen) {
setIsDialogOpen(true);
}
};
return (
<button onClick={handelClick}> click me </button> //on clicking this
//button should open the dialog. if dialog open
//and clicking this button again should close the dialog
{isDialogOpen &&
<Dialog setIsDialogOpen={setIsDialogOpen} buttonRef={buttonRef}/>
}
);
}
function Dialog({setIsDialogOpen, buttonRef}: Props) {
const dialogRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const handleClickOutsideDialog = (event: any) => {
if (
dialogRef && dialogRef.current &&
!dialogRef.current.contains(event.target) && buttonRef &&
buttonRef.current && !buttonRef.current.contains(event.target)
) {
setIsDialogOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutsideDialog);
return () => {
document.removeEventListener('mousedown', handleClickOutsideDialog);
};
}, [setIsDialogOpen, dialogRef]);
return (
<Wrapper ref={dialogRef}>
<Title> title </Title>
<Description> some big description </Description>
</Wrapper>
);
}
但是即使用户单击了“单击我”按钮,这也会使对话框保持打开状态。在对话框外部单击将关闭它。
【问题讨论】:
-
什么是“点击我按钮对话框”?你的意思是“点击我”按钮消失了吗?
-
不。单击单击我按钮使对话框消失并再次重新打开。
-
如果没有现场示例很难评估,但请尝试将您的按钮点击处理程序更改为
() => setIsDialogOpen((open) => !open) -
谢谢,但它是一样的。可能是因为对话框组件中的useeffect。我正在检查点击是否在对话框之外。因此,如果用户单击单击我按钮,则将其计为在对话框外单击,并且 isDialogOpen 设置为 false,然后再次设置为 true,因为单击我按钮 onclick 方法被调用????我怎样才能改变它
-
你能在这里上传你的 Wrapper 组件吗?
标签: javascript reactjs typescript