一、 BrowserRouter

1. 安装 React Router

npm install react-router-dom
或
yarn add react-router-dom

2. 基础路由配置

​(1) 基本结构

在 App.jsx 或入口文件中设置路由:

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import Aboutfrom './pages/About';
import Navbar from './pages/Navbar';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />      {/* 根路径 首页 */}
        <Route path="/about" element={<About/>} /> {/* 关于页*/}
      </Routes>
      <Navbar />
    </BrowserRouter>
  )
}

export default App

(2) 导航跳转

使用 <Link> 组件实现无刷新跳转(替代 <a> 标签):

import { Link } from 'react-router-dom';

function Navbar() {
  return (
    <nav>
      <Link to="/">首页</Link>      {/* 跳转到根路径 */}
      <Link to="/about">关于</Link>  {/* 跳转到关于页 */}
    </nav>
  );
}

3. 动态路由

通过 :param 定义动态参数(如用户ID):

// 路由配置
<Route path="/user/:userId" element={<UserPage />} />

// UserPage 组件中获取参数
import { useParams } from 'react-router-dom';

function UserPage() {
  const { userId } = useParams(); // 获取动态参数
  return <div>用户ID: {userId}</div>;
}

4. 嵌套路由

父路由下定义子路由,需用 <Outlet> 作为子路由的渲染出口:

// 父路由配置
<Route path="/dashboard" element={<Dashboard />}>
  <Route path="stats" element={<Stats />} />   {/* /dashboard/stats */}
  <Route path="settings" element={<Settings />} /> {/* /dashboard/settings */}
</Route>

// Dashboard 组件中放置 <Outlet>
function Dashboard() {
  return (
    <div>
      <h1>仪表盘</h1>
      <Outlet /> {/* 子路由内容在此渲染 */}
    </div>
  );
}

5. 编程式导航

通过 useNavigate Hook 实现代码跳转(如登录后跳转):

import { useNavigate } from 'react-router-dom';

function LoginButton() {
  const navigate = useNavigate();

  const handleLogin = () => {
    // 模拟登录逻辑...
    navigate('/dashboard'); // 跳转到仪表盘
  };

  return <button onClick={handleLogin}>登录</button>;
}

6. 路由守卫(权限控制)

通过高阶组件或包装组件实现登录验证:

// PrivateRoute 组件
import { Navigate } from 'react-router-dom';

function PrivateRoute({ children }) {
  const isAuthenticated = true; // 替换为实际登录状态判断
  return isAuthenticated ? children : <Navigate to="/login" replace />;
}

// 使用方式
<Route 
  path="/admin" 
  element={<PrivateRoute><AdminPage /></PrivateRoute>} 
/>

7. 404 页面处理

捕获所有未匹配的路由:

<Route path="*" element={<NotFoundPage />} /> {/* 404 页面 */}

8. 路由懒加载(代码分割)

结合 React.lazy 和 Suspense 实现按需加载:

import { lazy, Suspense } from 'react';

const LazyAbout = lazy(() => import('./pages/About'));

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>加载中...</div>}>
        <Routes>
          <Route path="/about" element={<LazyAbout />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

9. 路由模式

  • BrowserRouter​:基于 HTML5 History API(推荐,URL 无 #)。
  • HashRouter​:URL 带 #(兼容旧服务器)。
import { HashRouter } from 'react-router-dom';
<HashRouter>...</HashRouter>

10. 常见问题

​(1) 刷新页面后路由丢失?​

  • 确保服务器配置了 ​SPA 回退​(如 Nginx 的 try_files 或 Netlify 的 _redirects)。
  • 示例 Nginx 配置:
    location / {
      try_files $uri $uri/ /index.html;
    }

​(2) 如何传递状态给路由组件?​

使用 state 属性:

<Link to="/about" state={{ from: 'home' }}>关于</Link>

// About 组件中获取状态
import { useLocation } from 'react-router-dom';
const { state } = useLocation(); // { from: 'home' }

总结

功能 关键 API/组件
路由配置 BrowserRouterRoutesRoute
导航跳转 <Link>useNavigate
动态路由 :paramuseParams
嵌套路由 <Outlet>
权限控制 Navigate, 高阶组件
懒加载 React.lazySuspense

通过 React Router,你可以轻松实现复杂的单页应用(SPA)路由需求!

二、createBrowserRouter

import { createBrowserRouter } from 'react-router-dom';
import Home from '../pages/Home';
import Video from '../pages/Video';

// 创建路由配置
const router = createBrowserRouter(
    [
        {
            path: '/',
            element: <Home />,
        },
        {
            path: '/video',
            element: <Video />,
        },
    ],
    {
        basename: '', // ✅ 如果你的 base 是 './',这里设为空字符串
    }
);

export default router;

1. createBrowserRouter(...)

这是 React Router v6.4+ 提供的一个 ​工厂函数,用于 ​创建一个路由器实例(Router Object)​,它是 ​新一代更灵活、更强大路由配置方式的核心

它接收两个参数:

参数 类型 说明
第一个参数 RouteObject[] 路由配置数组,每个对象定义一条路由规则,包括 path 和 element 等
第二个参数 RouterOptions 可选的配置项,比如 basenamefuture 等

2. 路由配置数组(RouteObject[])

[
  { path: '/', element: <Home /> },
  { path: '/video', element: <Video /> },
  // ...其他路由
]

每一项是一个 ​路由对象(RouteObject)​,包含:

属性 说明
path 当前路由的路径,比如 '/''/video'
element 对应这个路径要渲染的 ​React 组件​(必须是 JSX 元素,比如 <Home />

⚠️ 注意:这里的 <Home /> 等组件需要 ​提前导入,比如:

import Home from './pages/Home';
import Video from './pages/Video';
// 以此类推

3. 配置项 { basename: '' }

  • basename 是部署应用时使用的 ​基础路径前缀
  • 比如,如果你的应用不是部署在网站根目录 /,而是部署在 /app/ 子路径下,那么你需要设置:
    basename: '/app'
  • 如果你的应用部署在网站根目录,或者 Vite 的 base: './',那么通常设为:
    basename: ''  // 或者 basename: '/'
  • 你这里设为 '' 是没问题的,表示路由匹配的是相对根路径的。

🧩 二、如何使用这个 router 对象?

你定义了 router,但 ​它本身不会自动生效,你还需要在应用的顶层使用一个 ​Router Provider​ 来激活路由功能。

✅ 正确用法:配合 <RouterProvider router={router} />

在你的 App.tsx(或入口组件)中,你应该这样使用:

// App.tsx
import { RouterProvider } from 'react-router-dom';
import router from './router'; // 假设你把上面的 router 定义放在了 src/router/index.tsx
import Navbar from './components/Navbar';

function App() {
  return (
    <>
      {/* 路由视图容器 */}
      <div className='main'>
        <RouterProvider router={router} /> {/* ✅ 这里启用路由 */}
      </div>

      {/* 如果有固定的导航栏、底部栏,可以放在路由外面 */}
      <Navbar />
    </>
  );
}

export default App;

✅ ​注意:<RouterProvider router={router} /> 是必须的!它会把路由上下文注入到 React Tree 中,这样 <Routes> 和 <Route> 或者 hooks(如 useNavigate)才能正常工作。​


🧩 三、这个路由方式的特点与优势

✅ 1. ​更灵活、可抽离的路由配置

  • 你可以把所有路由规则集中管理(比如在 src/router/index.tsx),便于维护和扩展。
  • 支持嵌套路由、动态路由、懒加载等高级功能(后续可扩展)。

✅ 2. ​使用 createBrowserRouter + RouterProvider 是 React Router v6.4+ 推荐的方式

  • 相比旧版的 <BrowserRouter><Routes>...</Routes></BrowserRouter> 写法,这种新方式更模块化,更适合大型项目。
  • 特别适合配合 ​数据加载、布局路由、嵌套路由​ 等高级功能。

✅ 3. ​支持 basename、未来特性配置

  • 比如你可以设置 basename: '/app' 来支持子路径部署。
  • 也可以通过 future 配置启用实验性功能。

🧩 四、对比传统写法(你可能之前用的)

❓ 你可能之前是这样写的(传统写法):

// App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/video" element={<Video />} />
        {/* 其它 Route */}
      </Routes>
    </BrowserRouter>
  );
}

🔁 ​对应到新写法就是:​

  • <BrowserRouter> → 由 createBrowserRouter(...) 创建的 router 对象代替
  • <Routes><Route> → 被抽离到路由配置数组中,作为 route objects
  • 整个路由系统由 <RouterProvider router={router} /> 激活

🧩 五、如何扩展?(未来你可以这样做)

✅ 嵌套路由

你可以在路由配置里使用 children 来定义子路由。

✅ 布局路由(Layout)

通过定义带有 <Outlet /> 的布局组件,实现统一 UI 布局(比如统一的 Header / Footer)。

✅ 懒加载路由

结合 React.lazy() 和 Suspense,实现路由组件的按需加载,优化性能。

✅ 路由数据加载(Loader)

在 v6.4+ 中还可以为路由定义 loader 函数,在进入路由前加载数据(类似 Next.js 的 getServerSideProps)。


✅ 总结:你这种路由方式如何使用?

1. ​定义路由配置

// src/router/index.tsx
import { createBrowserRouter } from 'react-router-dom';
import Home from '../pages/Home';
import Video from '../pages/Video';
// ... 其它组件导入

const router = createBrowserRouter(
  [
    { path: '/', element: <Home /> },
    { path: '/video', element: <Video /> },
    // 其它路由
  ],
  { basename: '' }
);

export default router;

2. ​在 App.tsx 中使用 RouterProvider 启用路由

// App.tsx
import { RouterProvider } from 'react-router-dom';
import router from './router';
import Navbar from './components/Navbar';

function App() {
  return (
    <>
      <div className='main'>
        <RouterProvider router={router} />  {/* ✅ 启用路由系统 */}
      </div>
      <Navbar /> {/* 静态导航,放在路由外 */}
    </>
  );
}

export default App;

3. ​访问页面

  • 打开 / → 渲染 <Home />
  • 打开 /video → 渲染 <Video />
  • 以此类推

✅ 最终推荐做法(结构清晰、可扩展)

src/
├── App.tsx
├── main.tsx
├── router/
│   └── index.tsx       // 路由配置集中管理
├── pages/
│   ├── Home.tsx
│   ├── Video.tsx
│   ├── Message.tsx
│   ├── Shopping.tsx
│   └── My.tsx
└── components/
    └── Navbar.tsx

❗注意事项

注意事项 说明
✅ 必须用 <RouterProvider router={router} /> 包裹,否则路由上下文不存在,会报错 比如 useNavigate() 或 <Routes> 无法工作
✅ 不要同时使用 <BrowserRouter> 和 RouterProvider 只选其中一种方式
✅ 确保所有 element: <Component /> 中的组件已正确导入 否则会报错 ReferenceError
✅ basename 通常设为 '' 或 '/',除非你部署在子路径下 比如 /app/ 则设为 basename: '/app'

三,路由跳转

一、使用 useNavigate() 进行编程式导航(推荐)

这是 ​最常用、最灵活的路由跳转方式,适用于按钮点击、表单提交后跳转、条件跳转等场景。

🧩 1. ​基本用法

步骤:
  1. ​**在组件中引入 useNavigate**​
  2. 调用 navigate(path) 进行跳转

✅ 示例代码

// src/pages/SomePage.tsx
import { useNavigate } from 'react-router-dom';

function SomePage() {
  const navigate = useNavigate();

  const handleClick = () => {
    // 跳转到 /video 页面
    navigate('/video');
  };

  return (
    <div>
      <h1>这是某个页面</h1>
      <button onClick={handleClick}>跳转到视频页</button>
    </div>
  );
}

export default SomePage;

✅ 可选参数

navigate 函数还可以接收 ​第二个参数,是一个对象,用于控制跳转行为:

navigate('/video', {
  replace: true,    // 替换当前历史记录,而不是新增(用户点击后退不会回到这个页面)
  state: { from: 'home' } // 传递状态数据(可在目标页面通过 useLocation().state 获取)
});
示例:
navigate('/video', { replace: true });
// 或者带状态
navigate('/video', { state: { id: 123, from: 'home' } });

✅ 二、使用 <Link> 组件进行声明式导航(类似 <a> 标签)

如果你想实现 ​类似普通超链接的导航(用户点击即可跳转,无 JS 交互逻辑)​,可以使用 React Router 提供的 <Link> 组件。

🧩 用法:

import { Link } from 'react-router-dom';

function NavBar() {
  return (
    <nav>
      <Link to="/">首页</Link>
      <Link to="/video">视频</Link>
      <Link to="/message">消息</Link>
      <Link to="/shopping">购物</Link>
      <Link to="/my">我的</Link>
    </nav>
  );
}

✅ 特点:

  • 点击后无刷新跳转(单页应用 SPA 特性)。
  • 支持 to 属性,值可以是字符串路径,如 to="/video"
  • 也可以传对象,比如带查询参数或状态:
    <Link to={{ pathname: '/video', search: '?t=123', state: { from: 'home' } }} />

✅ 三、在你的实际项目结构中如何组织?

假设你的路由配置是这样的(使用 <RouterProvider> 方式):

// src/router/index.tsx
import { createBrowserRouter } from 'react-router-dom';
import Home from '../pages/Home';
import Video from '../pages/Video';
import Message from '../pages/Message';
import Shopping from '../pages/Shopping';
import My from '../pages/My';

const router = createBrowserRouter([
  { path: '/', element: <Home /> },
  { path: '/video', element: <Video /> },
  { path: '/message', element: <Message /> },
  { path: '/shopping', element: <Shopping /> },
  { path: '/my', element: <My /> },
]);

export default router;

然后在 App.tsx 中使用:

// App.tsx
import { RouterProvider } from 'react-router-dom';
import router from './router';
import Navbar from './components/Navbar';

function App() {
  return (
    <>
      <div className='main'>
        <RouterProvider router={router} /> {/* ✅ 路由系统启动 */}
      </div>
      <Navbar /> {/* 导航栏,可以放<Link>或按钮跳转逻辑 */}
    </>
  );
}

export default App;

✅ 四、总结:路由跳转的 2 种主要方式

方式 用法 适用场景 是否需要导入
​**1. useNavigate()**​ 编程式导航,调用 navigate('/path') 按钮点击跳转、条件跳转、表单提交后跳转等 import { useNavigate } from 'react-router-dom'
​**2. <Link to="/path">**​ 声明式导航,类似 <a> 标签 导航栏、菜单、静态链接等 import { Link } from 'react-router-dom'

✅ 五、额外提示

1. ​**<Link> 不会引起页面刷新!​**​

  • 它是通过 History API 实现的单页跳转(SPA),和普通 <a href="/video"> 不一样,不会导致整页重新加载。

2. ​在路由之间传递数据

  • 通过 URL 参数(动态路由)​​:比如 /video/123 → 可用 useParams() 获取 123
  • 通过查询参数(search)​​:比如 /video?t=123 → 可用 useSearchParams() 解析
  • 通过状态(state)​​:navigate('/video', { state: { from: 'home' } }) → 可用 useLocation().state 获取

✅ 六、完整示例:跳转按钮 + 导航菜单

1. 组件内跳转(编程式,使用 useNavigate

// src/pages/Home.tsx
import { useNavigate } from 'react-router-dom';

function Home() {
  const navigate = useNavigate();

  return (
    <div>
      <h1>首页</h1>
      <button onClick={() => navigate('/video')}>去看视频</button>
    </div>
  );
}

2. 导航栏跳转(声明式,使用 <Link>

// src/components/Navbar.tsx
import { Link } from 'react-router-dom';

function Navbar() {
  return (
    <nav>
      <Link to="/">首页</Link> |
      <Link to="/video">视频</Link> |
      <Link to="/message">消息</Link> |
      <Link to="/shopping">购物</Link> |
      <Link to="/my">我的</Link>
    </nav>
  );
}

export default Navbar;

✅ 总结一句话

当你使用 ​**<RouterProvider router={router} />**​(React Router v6.4+ 的推荐方式)时,你仍然可以使用:

  • ​**useNavigate()​ 进行 ​编程式导航(如按钮跳转)​**​
  • ​**<Link to="...">​ 进行 ​声明式导航(如菜单链接)​**​

这两种方式是 React Router 中实现路由跳转的 ​标准、推荐且最常用的方法,无论你的路由配置是通过 <BrowserRouter> 还是 RouterProvider 管理,它们都能完美工作!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐