You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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项目缺少测试项目中的两个关键配置:

  1. 全局路由事件绑定:测试项目在组件外部通过Router实例(直接从next/router导入)绑定了路由事件,确保模块加载时就开始监听,不会因组件挂载时机错过事件触发。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:25:23