You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ShadCN Alert Dialog点击后立即关闭的问题求助

解决Dropdown菜单中AlertDialog弹窗打开后立即关闭的问题

问题描述

实现菜单交互时,选择删除操作需先弹出确认弹窗再执行,但点击菜单内的删除选项后,弹窗刚打开就立刻关闭,推测是菜单点击后自动关闭导致的。

原代码如下:

import Image from 'next/image';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Trash2 } from 'lucide-react';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog';

export default function Home() {
  return (
    <div>
      <DropdownMenu>
        <DropdownMenuTrigger>Open</DropdownMenuTrigger>
        <DropdownMenuContent>
          <DropdownMenuLabel>My Account</DropdownMenuLabel>
          <DropdownMenuSeparator />
          <DropdownMenuItem>
            <Trash2 className="mr-2 h-4 w-4" />
            <AlertDialog>
              <AlertDialogTrigger>Open</AlertDialogTrigger>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
                  <AlertDialogDescription>
                    This action cannot be undone. This will permanently delete
                    your account and remove your data from our servers.
                  </AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel>Cancel</AlertDialogCancel>
                  <AlertDialogAction>Continue</AlertDialogAction>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  );
}

问题根源

DropdownMenuItem点击后会默认触发菜单关闭,而AlertDialogTrigger的点击事件被菜单的关闭行为中断,导致弹窗随菜单一同关闭。

解决方案

通过手动控制菜单和弹窗的状态,阻止菜单默认关闭行为,实现弹窗正常显示:

'use client';
import { useState } from 'react';
import { Trash2 } from 'lucide-react';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';

export default function Home() {
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [isAlertOpen, setIsAlertOpen] = useState(false);

  const handleDeleteClick = (e: React.MouseEvent) => {
    // 阻止DropdownMenuItem默认关闭菜单的行为
    e.preventDefault();
    // 打开确认弹窗
    setIsAlertOpen(true);
  };

  const handleConfirmDelete = () => {
    // 此处替换为实际删除逻辑
    console.log('执行删除操作');
    // 关闭弹窗与菜单
    setIsAlertOpen(false);
    setIsMenuOpen(false);
  };

  const handleCancelDelete = () => {
    // 关闭弹窗与菜单
    setIsAlertOpen(false);
    setIsMenuOpen(false);
  };

  return (
    <div>
      <DropdownMenu open={isMenuOpen} onOpenChange={setIsMenuOpen}>
        <DropdownMenuTrigger>Open</DropdownMenuTrigger>
        <DropdownMenuContent>
          <DropdownMenuLabel>My Account</DropdownMenuLabel>
          <DropdownMenuSeparator />
          <DropdownMenuItem onClick={handleDeleteClick}>
            <Trash2 className="mr-2 h-4 w-4" />
            删除
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      <AlertDialog open={isAlertOpen} onOpenChange={setIsAlertOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>你确定要删除吗?</AlertDialogTitle>
            <AlertDialogDescription>
              此操作不可撤销,将永久删除你的账户并清除服务器上的数据。
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={handleCancelDelete}>取消</AlertDialogCancel>
            <AlertDialogAction onClick={handleConfirmDelete}>确认</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}

关键改动说明

  1. 状态管理:使用useState分别控制菜单(isMenuOpen)和弹窗(isAlertOpen)的打开状态,摆脱组件默认行为的限制
  2. 阻止默认行为:在handleDeleteClick中调用e.preventDefault(),避免DropdownMenuItem点击后自动关闭菜单
  3. 交互闭环:弹窗的确认/取消按钮点击时,同时关闭弹窗和菜单,完成完整的操作流程

内容的提问来源于stack exchange,提问作者Stykgwar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:06:09