将 NProgress 与 Next.js 结合使用(路由器和获取事件)

2025-06-10

将 NProgress 与 Next.js 结合使用(路由器和获取事件)

今天我尝试将 NProgress https://github.com/rstacruz/nprogress添加到我的 Next.js 项目中。

我希望进度条能够:

  1. 切换路线/页面时显示
  2. 显示何时进行任何提取调用
  3. 仅在延迟后显示,我不想在每次交互时都显示加载器,只在请求“缓慢”时显示

NProgress以下是其外观的演示:

NProgress 演示

由于我在实现这些的过程中遇到了一些挑战,我觉得有必要分享一下我是如何做到的。具体如下:

首先,安装nprogress包:

npm install nprogress
Enter fullscreen mode Exit fullscreen mode

然后编辑或创建您的_app.js并添加:

// global styles are required to be added to `_app.js` per Next.js requirements.
import "nprogress/nprogress.css";

const TopProgressBar = dynamic(
  () => {
    return import("components/TopProgressBar");
  },
  { ssr: false },
);

export default function MyApp({ Component, pageProps }) {
  return <>
    <TopProgressBar />
    <Component {...pageProps} />
  </>
}
Enter fullscreen mode Exit fullscreen mode

在这里我们使用动态导入和 ssr 选项来确保我们的TopProgressBar仅在浏览器环境中加载。

如果您想知道相对加载是如何components/TopProgressBar工作的,只需按照Next.js 文档jsconfig.json中所示进行配置即可

最后创建components/TopProgressBar.js

import Router from "next/router";
import NProgress from "nprogress";

let timer;
let state;
let activeRequests = 0;
const delay = 250;

function load() {
  if (state === "loading") {
    return;
  }

  state = "loading";

  timer = setTimeout(function () {
    NProgress.start();
  }, delay); // only show progress bar if it takes longer than the delay
}

function stop() {
  if (activeRequests > 0) {
    return;
  }

  state = "stop";

  clearTimeout(timer);
  NProgress.done();
}

Router.events.on("routeChangeStart", load);
Router.events.on("routeChangeComplete", stop);
Router.events.on("routeChangeError", stop);

const originalFetch = window.fetch;
window.fetch = async function (...args) {
  if (activeRequests === 0) {
    load();
  }

  activeRequests++;

  try {
    const response = await originalFetch(...args);
    return response;
  } catch (error) {
    return Promise.reject(error);
  } finally {
    activeRequests -= 1;
    if (activeRequests === 0) {
      stop();
    }
  }
};

export default function () {
  return null;
}
Enter fullscreen mode Exit fullscreen mode

这里我们注册了Next.js 路由器事件,并对全局获取进行了monkey patchfetch 。我之前担心 monkey patch会注册失败,但结果证明它成功了🤷‍♂️!

正如您所看到的,TopProgressBar什么都没有渲染,我猜这样做可能会有问题,所以如果您遇到问题,请告诉我!

就是这样!

如果您想知道NProgress由于提交数量少和问题数量“多”而是否仍在维护,那么好消息是他们正在开发 2020 年的新版本:https://github.com/rstacruz/nprogress/pull/218

即使您不使用 Next.js,您也应该能够将此代码适配到您最喜欢的平台或框架。

鏂囩珷鏉ユ簮锛�https://dev.to/vvo/show-a-top-progress-bar-on-fetch-and-router-events-in-next-js-4df3
PREV
在 React 中构建可重用列表组件
NEXT
如何在 Next.js 中使用 Fontawesome