如何在React应用中监测导航进度并结合NProgress实现全局进度条?
在React Router v6中结合NProgress实现全局导航进度条
核心思路
useNavigation 必须在路由上下文(RouterProvider 覆盖的组件树)内使用,所以不能通过 fallbackElement 实现。正确的做法是创建一个全局进度条组件,将其嵌入路由根布局中,这样就能监听所有导航状态变化,包括页面渲染、懒加载组件加载等过程。
实现步骤
1. 安装依赖
npm install nprogress # 或者 yarn add nprogress
2. 创建全局进度条组件
创建 ProgressBar.jsx,利用 useNavigation 监听导航状态,控制NProgress的启停:
import { useEffect } from 'react'; import { useNavigation } from 'react-router-dom'; import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; // 引入默认样式 const ProgressBar = () => { const { state } = useNavigation(); useEffect(() => { if (state === 'loading') { NProgress.start(); } else { NProgress.done(); } }, [state]); return null; // 仅监听状态,无需渲染DOM元素 }; export default ProgressBar;
3. 配置路由根布局
创建包含进度条和路由出口的根布局组件,确保进度条全局存在:
import { Outlet } from 'react-router-dom'; import ProgressBar from './ProgressBar'; const RootLayout = () => { return ( <> <ProgressBar /> <Outlet /> {/* 渲染所有子路由内容 */} </> ); }; export default RootLayout;
4. 配置RouterProvider
将根布局作为路由的顶层元素,传入 RouterProvider:
import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import RootLayout from './RootLayout'; import Home from './Home'; import About from './About'; // 懒加载组件示例 const Dashboard = React.lazy(() => import('./Dashboard')); const router = createBrowserRouter([ { path: '/', element: <RootLayout />, children: [ { index: true, element: <Home /> }, { path: 'about', element: <About /> }, { path: 'dashboard', element: ( <React.Suspense fallback={<div>页面加载中...</div>}> <Dashboard /> </React.Suspense> ) }, ], }, ]); function App() { return <RouterProvider router={router} />; } export default App;
关键细节说明
useNavigation的state包含三种状态:idle:无导航操作,处于空闲状态loading:正在加载路由组件(包括懒加载组件下载、页面渲染)submitting:正在提交表单(如使用React Router的Form组件)
- 若需自定义进度条样式,直接修改
nprogress.css或在全局样式中覆盖默认样式即可 - 如果组件内部有独立的异步数据加载(路由已完成匹配但数据未加载完),可在组件内手动调用
NProgress.start()和NProgress.done()补充控制
内容的提问来源于stack exchange,提问作者Loudrous
相关产品推荐
相关产品推荐

