Next.js 13中如何实现类似beforePopState的浏览器后退拦截功能
在Next.js 13中拦截浏览器后退按钮的方案
Next.js 13分为Pages Router和App Router两种架构,针对拦截浏览器后退的需求,两种架构的实现方式有所不同:
Pages Router 场景
Next.js 13的Pages Router完全兼容Next.js 12的beforePopState方法,用法和之前一致,直接通过useRouter调用即可:
import { useEffect } from 'react'; import { useRouter } from 'next/router'; export default function MyPage() { const router = useRouter(); useEffect(() => { const interceptBack = () => { const confirmLeave = window.confirm('确定要离开当前页面吗?'); return confirmLeave; }; router.beforePopState(interceptBack); // 组件卸载时清理拦截逻辑 return () => router.beforePopState(() => true); }, [router]); return <div>页面内容</div>; }
App Router 场景
App Router没有提供直接的beforePopState替代API,需要借助浏览器原生的popstate事件结合Next.js的路由工具来实现拦截:
'use client'; import { useEffect } from 'react'; import { useRouter } from 'next/navigation'; export default function MyAppPage() { const router = useRouter(); useEffect(() => { const handlePopState = (e) => { const confirmBack = window.confirm('确定要后退吗?'); if (confirmBack) { // 用户确认后退,移除监听避免重复拦截 window.removeEventListener('popstate', handlePopState); } else { // 阻止默认后退行为,同时添加当前页面到历史栈抵消浏览器的后退操作 e.preventDefault(); window.history.pushState(null, '', window.location.href); } }; // 初始化时添加当前页面到历史栈,避免首次后退出现异常 window.history.pushState(null, '', window.location.href); window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, [router]); return <div>App Router 页面内容</div>; }
注意事项
- App Router下必须添加
'use client'指令,因为代码依赖浏览器端的window对象和DOM事件 - 手动调用
pushState是为了抵消浏览器的后退操作,确保历史栈保持当前页面状态 - 如果需要区分前进/后退动作,可以通过记录历史栈长度或自定义
pushState的状态参数来实现更精细的控制
内容的提问来源于stack exchange,提问作者Abhishek Tiwari
相关产品推荐
相关产品推荐

