Next.js 13.4 App目录下实现全局路由切换加载器方案咨询
在Next.js 13.4 App目录实现全局路由切换加载器的方案
在Next.js 13.4的App Router架构下,实现全局路由切换加载器可以通过以下几种原生或自定义方案解决,不需要依赖已移除的导航事件监听器:
方案一:利用useRouter的isPending状态(最简便的原生方案)
Next.js 13.4+的App Router中,next/navigation提供的useRouter钩子新增了isPending属性,会在路由切换(包括客户端导航和路由预加载)时自动切换为true,完成后恢复为false。你可以直接在根布局中基于这个状态渲染全局加载器。
示例代码:
// app/layout.tsx import { useRouter } from 'next/navigation'; import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { const router = useRouter(); return ( <html lang="en"> <body> {/* 全局加载器 */} {router.isPending && ( <div className="global-loader"> <div className="loader-spinner"></div> </div> )} {children} </body> </html> ); }
对应的全局样式(globals.css):
.global-loader { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.9); display: flex; align-items: center; justify-content: center; z-index: 9999; } .loader-spinner { width: 48px; height: 48px; border: 5px solid #000; border-bottom-color: transparent; border-radius: 50%; animation: rotation 1s linear infinite; } @keyframes rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
方案二:自定义拦截Link组件(补充边缘场景)
如果遇到isPending未覆盖的导航场景(比如某些自定义触发的路由跳转),可以封装一个自定义Link组件,手动管理加载状态,同时结合isPending保证一致性:
// components/CustomLink.tsx import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useState, useEffect } from 'react'; type CustomLinkProps = React.ComponentProps<typeof Link>; export default function CustomLink({ children, ...props }: CustomLinkProps) { const router = useRouter(); const [isNavigating, setIsNavigating] = useState(false); const handleClick = () => { setIsNavigating(true); }; // 路由切换完成后重置状态 useEffect(() => { if (!router.isPending) { setIsNavigating(false); } }, [router.isPending]); // 合并两种状态确保加载器覆盖所有导航场景 const showLoader = isNavigating || router.isPending; return ( <> <Link {...props} onClick={handleClick}> {children} </Link> </> ); }
使用时直接替换原生Link为CustomLink即可,加载器仍复用根布局中的全局组件。
方案三:结合页面loading.tsx实现全局+局部加载
如果你的页面有单独的loading.tsx(页面级骨架屏),可以让全局加载器在路由切换初期显示,页面级加载组件接管后续状态,避免重复加载提示。只需要保证根布局的全局加载器在isPending为true时显示即可,页面的loading.tsx会自动在组件数据获取时渲染。
注意事项
- 确保全局加载器的CSS使用
fixed定位,避免被页面内容遮挡。 - 对于服务端渲染的路由切换,
isPending同样会生效,因为Next.js会在客户端导航开始时同步更新这个状态。
内容的提问来源于stack exchange,提问作者Ravi Shankar
相关产品推荐
相关产品推荐

