Reactアプリにプログレスバーを手軽に組み込める@bprogress/reactを試してみた
Webアプリでページ遷移やデータ取得中に、「今何かロードしてるんだよ、待っててね」って手軽に画面に表示したいときってありますよね?
@bprogress/react を使うと、ルーターに依存せずReactアプリへ簡単にプログレスバーを組み込めます。
触ってみたら思ったよりも自由度が高くて面白かったので紹介します。
まずはStackBlitzのデモを触ってみてください。
Fetch data をクリックすると、2秒間上部にバーが走ってロード中の雰囲気が出ます。
@bprogress/reactとは
@bprogress/react はNProgressをベースにした、TypeScript製のプログレスバーライブラリです。
特徴的なのは ルーター非依存 である点です。
Next.js向けの next-nprogress-bar のようなライブラリはルーターのイベントに自動でフックしますが、@bprogress/react は useProgress フックで start() / stop() を自分で呼ぶ設計になっています。「自動でやってほしい」という場合には useAnchorProgress フックも用意されていますが、基本的には自分で制御する前提のライブラリです。
React以外にもNext.js・Remix・Vue向けの専用パッケージが用意されています。
インストール
npm install @bprogress/react
# or
pnpm add @bprogress/react
基本的な使い方
1. ProgressProviderでアプリ全体をラップする
ProgressProvider をアプリのルートに配置します。disableStyle を指定するとデフォルトのスタイルを無効化でき、後述の css() 関数で独自スタイルを完全に制御できます。
import { ProgressProvider } from '@bprogress/react';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<ProgressProvider disableStyle>
<App />
</ProgressProvider>
</React.StrictMode>
);
2. useProgressフックでバーを操作する
useProgress フックが返す start() / stop() / pause() / resume() でバーをコントロールします。
import { useProgress } from '@bprogress/react';
function App() {
const { start, stop, pause, resume } = useProgress();
return (
<div>
<button onClick={() => start()}>start()</button>
<button onClick={() => stop()}>stop()</button>
<button onClick={() => pause()}>pause()</button>
<button onClick={() => resume()}>resume()</button>
</div>
);
}
非常にシンプルです。APIフェッチと組み合わせる場合は次のようになります。
const { start, stop } = useProgress();
const handleFetch = async () => {
start();
await fetchData();
stop();
};
デモで確認できる機能
今回作ったデモでは以下の項目をインタラクティブに切り替えられます。
| 項目 | 内容 |
|---|---|
| Basic controls | start() / stop() / pause() / resume() を手動で呼ぶ |
| Simulated fetch | start() → 2秒待機 → stop() でAPIフェッチをシミュレート |
| Color | バーの色をBlue / Green / Pink / Orangeから選択 |
| Height | バーの太さを2px / 3px / 4px / 6pxから選択 |
| Speed | アニメーション速度をSlow / Normal / Fastから選択 |
| Easing | アニメーションの変化関数(linear / ease / ease-in-out / cubic-bezier) |
| Spinner | スピナーの表示・非表示と表示位置(4隅) |
| Direction | バーが伸びる方向(LTR(Left To Right) / RTL(Right To Left)) |
| Trickle | 自動で少しずつ進む"trickle"機能のON/OFFと速度 |
カスタマイズ方法
setOptions()で動的に変更する
useProgress が返す setOptions() を使うと、実行時にオプションを変更できます。
const { setOptions } = useProgress();
// アニメーション速度を変更
setOptions({ speed: 800 });
// イージングを変更
setOptions({ easing: "cubic-bezier(0.34, 1.56, 0.64, 1)" });
// スピナーを表示する
setOptions({ showSpinner: true });
// RTLモードに切り替える
setOptions({ direction: "rtl" });
// trickle(自動進行)を無効化する
setOptions({ trickle: false });
css()関数でスタイルを動的に変更する
@bprogress/core の css() 関数を使うと、色・高さ・スピナー位置をまとめたCSS文字列を生成できます。それを <style> タグに流し込むことで、まとめてスタイルを切り替えられます。
import { css } from "@bprogress/core";
import type { SpinnerPosition } from "@bprogress/react";
function applyProgressCss(
color: string,
height: string,
spinnerPosition: SpinnerPosition,
) {
const id = "bprogress-custom";
let el = document.getElementById(id) as HTMLStyleElement | null;
if (!el) {
el = document.createElement("style");
el.id = id;
document.head.appendChild(el);
}
el.textContent = css({ color, height, spinnerPosition });
}
// 色・高さ・スピナー位置を一括変更
applyProgressCss("#22c55e", "4px", "top-right");
おわりに
@bprogress/react を試してみました。ルーター非依存で useProgress フックを呼ぶだけというシンプルな設計が気に入りました。
軽くロード中であることを見せるのに使えそうです。
Next.jsやRemix向けの専用パッケージも用意されているので、フレームワークを使っている場合はそちらも検討してみてください。








