如何阻止点击Next.js Link内的按钮时触发链接跳转?
解决Next.js Link组件内按钮触发跳转的问题
我在使用Next.js的Link组件跳转到指定URL时,遇到了一个问题——点击Link内部的按钮时,会意外触发Link的跳转行为。我试过在DialogTrigger内的按钮onClick事件中使用event.stopPropagation(),但没有效果。以下是我的CardItem组件代码:
<Link href={`/fundraiser/${id}`}> <Card className="w-[360px] h-[500px] flex flex-col justify-between"> <div> <CardHeader> <CardTitle>{formattedTitle}</CardTitle> <CardDescription>{formattedDescription}</CardDescription> <CardDescription>{`By ${username}`}</CardDescription> </CardHeader> <CardContent> <div>{formattedContent}</div> </CardContent> </div> <div> <CardHeader> <CardDescription>raised {amountRaised}</CardDescription> </CardHeader> <CardFooter> <Progress className="h-2 " value={value} /> </CardFooter> <CardFooter className="flex flex-row items-center justify-center gap-3"> {button && ( <Button className="bg-teal-500 text-white py-2 px-4 rounded-md w-full"> Contribute </Button> )} {button && ( <Dialog> <DialogTrigger asChild > <Button onClick={handleClick} >Open</Button> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Are you sure absolutely sure?</DialogTitle> <DialogDescription> This action cannot be undone. This will permanently delete your account and remove your data from our servers. </DialogDescription> </DialogHeader> </DialogContent> </Dialog> )} </CardFooter> </div> </Card> </Link>
可行解决方法
方法1:使用event.preventDefault()阻止默认跳转
Next.js的Link组件基于原生<a>标签实现,点击事件最终会触发<a>的默认跳转行为。stopPropagation()只能阻止事件冒泡,无法拦截默认行为,所以需要在按钮的点击事件中调用event.preventDefault():
<Button onClick={(e) => { e.preventDefault(); handleClick(); }}>Open</Button>
方法2:将跳转逻辑移到Card点击事件,排除按钮区域
移除外层的Link组件,给Card添加点击事件处理跳转,同时在按钮的点击事件中阻止事件冒泡:
import { useRouter } from 'next/router'; // 在组件内获取router实例 const router = useRouter(); // 组件JSX部分 <Card className="w-[360px] h-[500px] flex flex-col justify-between" onClick={() => router.push(`/fundraiser/${id}`)} > {/* 原有卡片内容 */} <Button onClick={(e) => { e.stopPropagation(); handleClick(); }}>Open</Button> </Card>
方法3:拆分Link的包裹区域
只让需要跳转的卡片区域被Link包裹,按钮部分放在Link之外,这样点击按钮就不会触发Link的跳转:
<Card className="w-[360px] h-[500px] flex flex-col justify-between"> <Link href={`/fundraiser/${id}`}> <div style={{ cursor: 'pointer' }}> <div> <CardHeader> <CardTitle>{formattedTitle}</CardTitle> <CardDescription>{formattedDescription}</CardDescription> <CardDescription>{`By ${username}`}</CardDescription> </CardHeader> <CardContent> <div>{formattedContent}</div> </CardContent> </div> <div> <CardHeader> <CardDescription>raised {amountRaised}</CardDescription> </CardHeader> <CardFooter> <Progress className="h-2 " value={value} /> </CardFooter> </div> </div> </Link> <CardFooter className="flex flex-row items-center justify-center gap-3"> {button && ( <Button className="bg-teal-500 text-white py-2 px-4 rounded-md w-full"> Contribute </Button> )} {button && ( <Dialog> <DialogTrigger asChild > <Button onClick={handleClick} >Open</Button> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Are you sure absolutely sure?</DialogTitle> <DialogDescription> This action cannot be undone. This will permanently delete your account and remove your data from our servers. </DialogDescription> </DialogHeader> </DialogContent> </Dialog> )} </CardFooter> </Card>
内容的提问来源于stack exchange,提问作者Aditya
相关产品推荐
相关产品推荐

