NextJS14 + URQL全局错误处理器中页面重定向遇阻求助
解决Next.js 14 + URQL全局错误重定向问题
方案1:直接使用浏览器原生跳转(简单直接)
mapExchange的onError运行在客户端环境(URQL客户端在根布局创建,属于客户端组件),可以直接调用浏览器原生的location对象实现跳转,注意先判断当前是否处于浏览器环境:
mapExchange({ onError(error, operation) { console.log(`The operation ${operation.key} has errored with:`, error); // 匹配你需要捕获的特定错误,比如错误信息、错误类型 if (error.message.includes("未授权") || error.name === "AuthError") { if (typeof window !== 'undefined') { // 使用replace避免用户回退到原未授权页面 window.location.replace("/login"); } } }, });
方案2:结合React状态与Next.js路由(更贴合框架生态)
如果不想直接操作window,可以通过在根客户端组件中维护重定向状态,再用Next.js的useRouter实现跳转:
- 创建一个客户端组件包装器,维护重定向状态并暴露全局调用方法:
// app/components/AuthRedirectWrapper.tsx 'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; export default function AuthRedirectWrapper({ children }: { children: React.ReactNode }) { const [redirectPath, setRedirectPath] = useState<string | null>(null); const router = useRouter(); useEffect(() => { if (redirectPath) { router.push(redirectPath); setRedirectPath(null); } }, [redirectPath, router]); // 将重定向方法挂载到window,让URQL的onError可以调用 useEffect(() => { (window as any).triggerAuthRedirect = (path: string) => { setRedirectPath(path); }; return () => { delete (window as any).triggerAuthRedirect; }; }, []); return children; }
- 在根布局中引入这个包装器:
// app/layout.tsx import AuthRedirectWrapper from './components/AuthRedirectWrapper'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body> <AuthRedirectWrapper>{children}</AuthRedirectWrapper> </body> </html> ); }
- 在URQL的
mapExchange中调用全局重定向方法:
mapExchange({ onError(error, operation) { console.log(`The operation ${operation.key} has errored with:`, error); if (error.message.includes("未授权") || error.name === "AuthError") { if (typeof window !== 'undefined' && (window as any).triggerAuthRedirect) { (window as any).triggerAuthRedirect("/login"); } } }, });
关于之前方法失效的原因
useRouter是React Hook,必须在组件或自定义Hook的顶层调用,无法在普通函数(比如onError)中直接使用。next/navigation的redirect函数仅适用于服务器组件,在客户端组件中调用会抛出NEXT_REDIRECT错误,因为它是为服务器端跳转逻辑设计的。
内容的提问来源于stack exchange,提问作者JoJ
相关产品推荐
相关产品推荐

