NextJS + TypeScript路由变更无日志及加载条失效排查
解决Next.js项目中NProgress加载条不工作及路由事件无日志的问题
问题描述
我在给Next.js项目添加加载条时遇到两个问题:
- 路由导航时控制台没有路由事件日志输出
- 路由切换时加载条无法正常工作
我的_app.tsx代码如下:
import React, { useEffect } from "react"; import type { AppProps } from "next/app"; import "./global.css"; import { useRouter } from "next/router"; import NProgress from "nprogress"; import "nprogress/nprogress.css"; export default function MyApp({ Component, pageProps }: AppProps) { const router = useRouter(); useEffect(() => { const handleStart = (url: string) => { console.log(`Loading: ${url}`); NProgress.start(); }; const handleStop = (url: string) => { console.log(`done: ${url}`); NProgress.done(); }; router.events.on("routeChangeStart", handleStart); router.events.on("routeChangeComplete", handleStop); router.events.on("routeChangeError", handleStop); return () => { router.events.off("routeChangeStart", handleStart); router.events.off("routeChangeComplete", handleStop); router.events.off("routeChangeError", handleStop); }; }, [router]); return ( <div id="root" suppressHydrationWarning> <Component {...pageProps} /> </div> ); }
我创建了一个无TypeScript的测试项目,其_app.js能正常工作(加载条显示、控制台有日志),代码如下:
import React, { useEffect } from 'react'; import '../styles/globals.css'; import Layout from '../components/layout/Layout'; import { useRouter } from 'next/router'; import Router from 'next/router'; import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; Router.events.on('routeChangeStart', () => NProgress.start()); Router.events.on('routeChangeComplete', () => NProgress.done()); Router.events.on('routeChangeError', () => NProgress.done()); NProgress.configure({ showSpinner: false }); function MyApp({ Component, pageProps }) { const router = useRouter(); useEffect(() => { const handleStart = (url) => { console.log(`Loading: ${url}`); NProgress.start(); }; const handleStop = (url) => { console.log(`done: ${url}`); NProgress.done(); }; router.events.on('routeChangeStart', handleStart); router.events.on('routeChangeComplete', handleStop); router.events.on('routeChangeError', handleStop); return () => { router.events.off('routeChangeStart', handleStart); router.events.off('routeChangeComplete', handleStop); router.events.off('routeChangeError', handleStop); }; }, [router]); return ( <Layout> <Component {...pageProps} /> </Layout> ); } export default MyApp;
问题原因及解决方案
你的TS项目缺少测试项目中的两个关键配置:
- 全局路由事件绑定:测试项目在组件外部通过
Router实例(直接从next/router导入)绑定了路由事件,确保模块加载时就开始监听,不会因组件挂载时机错过事件触发。 - NProgress配置:调用
NProgress.configure()可以初始化加载条的行为和样式,避免默认配置导致的显示异常。
修改后的_app.tsx代码如下:
import React, { useEffect } from "react"; import type { AppProps } from "next/app"; import "./global.css"; import { useRouter, Router } from "next/router"; // 新增导入Router实例 import NProgress from "nprogress"; import "nprogress/nprogress.css"; // 全局绑定路由事件,模块加载阶段即生效 Router.events.on("routeChangeStart", () => NProgress.start()); Router.events.on("routeChangeComplete", () => NProgress.done()); Router.events.on("routeChangeError", () => NProgress.done()); // 配置加载条,例如隐藏默认的spinner NProgress.configure({ showSpinner: false }); export default function MyApp({ Component, pageProps }: AppProps) { const router = useRouter(); useEffect(() => { const handleStart = (url: string) => { console.log(`Loading: ${url}`); NProgress.start(); }; const handleStop = (url: string) => { console.log(`done: ${url}`); NProgress.done(); }; router.events.on("routeChangeStart", handleStart); router.events.on("routeChangeComplete", handleStop); router.events.on("routeChangeError", handleStop); return () => { router.events.off("routeChangeStart", handleStart); router.events.off("routeChangeComplete", handleStop); router.events.off("routeChangeError", handleStop); }; }, [router]); return ( <div id="root" suppressHydrationWarning> <Component {...pageProps} /> </div> ); }
额外检查项:
- 确保路由切换使用Next.js的
<Link>组件(客户端路由),原生<a>标签会触发页面刷新,不会触发客户端路由事件。 - 确认
nprogress包已正确安装(执行npm install nprogress或yarn add nprogress)。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

