stopPropagation 不适用于 Ant 设计下拉菜单

问题描述 投票:0回答:1

我有一个卡片组件包裹在 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>
  );
};
reactjs next.js antd preventdefault stoppropagation
1个回答
0
投票

我终于找到了答案,我在这里分享它,以防它可以帮助其他人。 在 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>
  );
© www.soinside.com 2019 - 2024. All rights reserved.