Next.js 13中如何让Link组件先执行onClick再路由?
问题解答
背景
我正在使用Next.js 13,同时采用Apollo Client存储客户端变量。
需求
希望在跳转到href指定的路由地址之前,先执行onClick函数。
代码示例
<Link href={`/session/${session.id}`} onClick={() => { updateDialogVars({ dialogOpen: ATTENDANCE_DIALOG, }) }} > <div> stuff </div> </Link>
其中updateDialogVars是一个mutation,用于更新Apollo Client中的响应式变量。
问题
能否使用Next.js的Link组件实现先执行onClick事件再进行路由跳转?是否只能将Link替换为div,在onClick执行完成后通过Next Router来触发路由跳转?
解决方案
分两种场景处理:
同步操作场景
如果updateDialogVars是同步更新变量的逻辑(比如直接修改Apollo的响应式变量,无异步请求),你当前的写法完全可行。Link组件的onClick事件会先于路由跳转执行,状态更新完成后才会触发页面跳转。异步操作场景
如果updateDialogVars是异步mutation(比如包含网络请求,返回Promise),直接使用Link会导致路由跳转可能在mutation完成前触发,状态未完成更新。此时有两种实现方式:- 方式一:保留Link组件,阻止默认跳转后手动触发
阻止Link的默认跳转行为,等待异步操作完成后,通过Next.js的router手动跳转:import { useRouter } from 'next/navigation'; const YourComponent = () => { const router = useRouter(); const handleClick = async (e) => { // 阻止Link的默认跳转行为 e.preventDefault(); // 执行异步mutation await updateDialogVars({ variables: { dialogOpen: ATTENDANCE_DIALOG } }); // 手动执行路由跳转 router.push(`/session/${session.id}`); }; return ( <Link href={`/session/${session.id}`} onClick={handleClick}> <div>stuff</div> </Link> ); }; - 方式二:替换为div,通过Router手动跳转
把Link换成普通的div,在onClick中完成异步操作后调用router.push:import { useRouter } from 'next/navigation'; const YourComponent = () => { const router = useRouter(); const handleClick = async () => { await updateDialogVars({ variables: { dialogOpen: ATTENDANCE_DIALOG } }); router.push(`/session/${session.id}`); }; return ( <div onClick={handleClick} style={{ cursor: 'pointer' }}> stuff </div> ); };
- 方式一:保留Link组件,阻止默认跳转后手动触发
两种方式都能实现“先执行操作再跳转”的需求,可根据代码习惯选择。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

