我有一个卡片组件包裹在 nextjs 链接内。该卡片由正文和页脚组成。这是我的卡片页脚。在 cardFooter 内部,我有一个包含两个项目的 Ant Design 下拉菜单。正如您所看到的,我几乎在所有可能导致链接触发的地方都放置了 PreventDefault 和 stopPropagation,但当我单击“共享”下拉菜单项时,它仍然首先显示模式,当我关闭模式时,页面导航到链接的地址。
Next js 13.4 和 ant design 5.12.5
const CardFooter: React.FC<CardFooterProps> = ({ adItem }) => {
const [showShareDialog, setShowShareDialog] = useState<boolean>(false);
const { token } = useToken();
const handleModalChange = () => {
setShowShareDialog((prev) => !prev);
};
return (
<div className={`flex h-[32px] justify-between`}>
<Space>
<ActionMenu
onShare={handleModalChange}
onReport={() => console.log('reported')}
/>
<ShareAd
onChange={handleModalChange}
openDialog={showShareDialog}
adItem={adItem}
/>
</Space>
</div>
);
};
这是我的 ActionMenu 组件:
const items: MenuProps['items'] = [
{
key: 'report',
label: 'rep',
danger: true,
icon: <ExclamationCircleOutlined />,
},
{
key: 'share',
label: 'shr',
icon: <ShareAltOutlined />,
},
];
const ActionMenu: FC<ActionMenuProps> = ({ onReport, onShare }) => {
const handleReportClick: MenuProps['onClick'] = (e) => {
// doesn't trigger Link component
onReport();
};
const handleShareClick: MenuProps['onClick'] = (e) => {
e.domEvent.preventDefault();
e.domEvent.stopPropagation();
//even with stopPropagation and preventDefault it triggers Link component
onShare();
};
const handleMenuClick: MenuProps['onClick'] = (e) => {
e.domEvent.preventDefault();
e.domEvent.stopPropagation();
switch (e.key) {
case 'report':
handleReportClick(e);
break;
case 'share':
handleShareClick(e);
break;
}
};
const menuProps = {
items,
onClick: handleMenuClick,
};
return (
<Dropdown menu={menuProps} trigger={['click']}>
<Button
key={'more'}
type={'text'}
shape={'circle'}
icon={<EllipsisOutlined />}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}}
/>
</Dropdown>
);
};
这是我的 ShareAd 组件,以防有帮助:
const ShareAd: React.FC<ShareAdProps> = ({ openDialog, onChange, adItem }) => {
const [linkCopied, setLinkCopied] = useState<boolean>(false);
const handleCopyLink = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
const itemLink = window.location.href + createLink('Item', adItem);
navigator.clipboard.writeText(itemLink);
setLinkCopied(true);
};
const modalOkHandler = () => {
setLinkCopied(false);
onChange();
};
const modalCancelHandler = () => {
setLinkCopied(false);
onChange();
};
return (
<Modal
title='share'
open={openDialog}
onCancel={modalCancelHandler}
centered
footer={
<Button onClick={modalOkHandler} type='primary'>
close
</Button>
}
>
<p className='mb-2'>share with friends</p>
<Button onClick={handleCopyLink} type='default' className='w-full'>
<CopyOutlined />
{linkCopied ? 'copied' : 'copy'}
</Button>
</Modal>
);
};
我终于找到了答案,我在这里分享它,以防它可以帮助其他人。 在 shareAd 组件中,我将 modalRender 属性添加到 antd Modal 组件中,如下所示。还在模态的 onCancel 上添加 e.stopPropagation() :
const modalCancelHandler = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
setLinkCopied(false);
onChange();
};
return (
<Modal
title='share'
open={openDialog}
onCancel={modalCancelHandler}
modalRender={(modal) => (
<div onClick={(e) => e.stopPropagation()}>{modal}</div>
)}
centered
footer={
<Button onClick={modalOkHandler} type='primary'>
close
</Button>
}
>
<p className='mb-2'>share with friends</p>
<Button onClick={handleCopyLink} type='default' className='w-full'>
<CopyOutlined />
{linkCopied ? 'copied' : 'copy'}
</Button>
</Modal>
);