React Router
10月 1, 2025
此内容为转载文章,原文链接: https://reactrouter.com.cn/
React Router 是一个适用于 React 的多策略路由器,这里详细介绍如何在 React 项目中使用 React Router。
🔧 安装与基础设置#
1. 安装 React Router#
# 使用 npm
npm install react-router-dom
# 使用 yarn
yarn add react-router-dom
# 使用 bun
bun add react-router-dom2. 基础路由设置#
// main.jsx 或 index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
)🎯 核心组件与 Hook#
1. 基本路由配置#
// App.jsx
import { Routes, Route } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Contact from './pages/Contact'
import Navbar from './components/Navbar'
function App() {
return (
<div className="app">
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</div>
)
}
export default App2. 导航组件#
// components/Navbar.jsx
import { Link, NavLink } from 'react-router-dom'
function Navbar() {
return (
<nav>
{/* Link - 普通导航链接 */}
<Link to="/">首页</Link>
{/* NavLink - 支持激活状态的链接 */}
<NavLink
to="/about"
className={({ isActive }) => isActive ? 'active' : ''}
>
关于我们
</NavLink>
<NavLink to="/contact">
{({ isActive }) => (
<span className={isActive ? 'text-blue-500' : ''}>
联系我们
</span>
)}
</NavLink>
</nav>
)
}🔄 动态路由与参数#
1. 动态路由参数#
// App.jsx - 路由配置
<Routes>
<Route path="/users" element={<UserList />} />
<Route path="/users/:userId" element={<UserProfile />} />
<Route path="/products/:category/:id" element={<ProductDetail />} />
</Routes>2. 获取路由参数#
// pages/UserProfile.jsx
import { useParams, useSearchParams } from 'react-router-dom'
function UserProfile() {
// 获取路径参数
const { userId } = useParams()
// 获取查询参数
const [searchParams, setSearchParams] = useSearchParams()
const tab = searchParams.get('tab')
const sort = searchParams.get('sort')
const updateQueryParams = () => {
setSearchParams({ tab: 'info', sort: 'asc' })
}
return (
<div>
<h1>用户资料: {userId}</h1>
<p>当前标签: {tab}</p>
<button onClick={updateQueryParams}>更新查询参数</button>
</div>
)
}🎪 编程式导航#
// components/LoginForm.jsx
import { useNavigate, useLocation } from 'react-router-dom'
function LoginForm() {
const navigate = useNavigate()
const location = useLocation()
const handleLogin = async () => {
try {
// 模拟登录逻辑
await loginUser()
// 登录后跳转
const from = location.state?.from?.pathname || '/dashboard'
navigate(from, { replace: true })
// 其他导航方式
// navigate(-1) // 返回上一页
// navigate('/dashboard', { state: { user: userData } }) // 传递状态
} catch (error) {
console.error('登录失败')
}
}
return (
<form onSubmit={(e) => {
e.preventDefault()
handleLogin()
}}>
{/* 表单内容 */}
<button type="submit">登录</button>
</form>
)
}🏗️ 嵌套路由#
1. 定义嵌套路由#
// App.jsx
<Routes>
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<DashboardHome />} />
<Route path="profile" element={<Profile />} />
<Route path="settings" element={<Settings />} />
<Route path="analytics" element={<Analytics />} />
</Route>
</Routes>2. 布局组件中使用 Outlet#
// layouts/DashboardLayout.jsx
import { Outlet, Link } from 'react-router-dom'
function DashboardLayout() {
return (
<div className="dashboard-layout">
<aside className="sidebar">
<nav>
<Link to="/dashboard">概览</Link>
<Link to="/dashboard/profile">个人资料</Link>
<Link to="/dashboard/settings">设置</Link>
<Link to="/dashboard/analytics">分析</Link>
</nav>
</aside>
<main className="main-content">
{/* 子路由将在这里渲染 */}
<Outlet />
</main>
</div>
)
}🛡️ 保护路由与权限控制#
1. 路由保护组件#
// components/ProtectedRoute.jsx
import { Navigate, useLocation } from 'react-router-dom'
function ProtectedRoute({ children, requiredRole }) {
const location = useLocation()
const { user, isAuthenticated } = useAuth() // 假设有认证 Hook
if (!isAuthenticated) {
// 重定向到登录页,并保存当前位置以便登录后返回
return <Navigate to="/login" state={{ from: location }} replace />
}
if (requiredRole && user.role !== requiredRole) {
// 权限不足
return <Navigate to="/unauthorized" replace />
}
return children
}2. 使用保护路由#
// App.jsx
<Routes>
<Route path="/admin" element={
<ProtectedRoute requiredRole="admin">
<AdminLayout />
</ProtectedRoute>
}>
<Route index element={<AdminDashboard />} />
<Route path="users" element={<UserManagement />} />
</Route>
<Route path="/profile" element={
<ProtectedRoute>
<UserProfile />
</ProtectedRoute>
} />
</Routes>📚 高级功能#
1. 懒加载路由#
import { lazy, Suspense } from 'react'
const LazyDashboard = lazy(() => import('./pages/Dashboard'))
const LazyAdmin = lazy(() => import('./pages/Admin'))
function App() {
return (
<Routes>
<Route
path="/dashboard"
element={
<Suspense fallback={<div>加载中...</div>}>
<LazyDashboard />
</Suspense>
}
/>
</Routes>
)
}2. 404 页面处理#
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Routes>3. 路由配置对象(v6.4+ 数据路由)#
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
const router = createBrowserRouter([
{
path: '/',
element: <RootLayout />,
children: [
{ index: true, element: <Home /> },
{
path: 'users',
element: <Users />,
loader: usersLoader, // 数据加载器
action: userAction // 数据操作
}
]
}
])
// 在 main.jsx 中使用
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
)💡 最佳实践#
- 文件组织:
src/
components/
pages/
Home.jsx
About.jsx
users/
UserList.jsx
UserProfile.jsx
layouts/
MainLayout.jsx
DashboardLayout.jsx
routes/
index.jsx- 路由集中管理:
// routes/index.jsx
import { useRoutes } from 'react-router-dom'
import routesConfig from './routesConfig'
function Router() {
return useRoutes(routesConfig)
}
export default Router- 类型安全(使用 TypeScript):
// types/router.d.ts
declare module 'react-router-dom' {
interface ParamKeys {
userId: string
productId: string
}
}React Router 提供了强大而灵活的路由解决方案,从简单的 SPA 导航到复杂的企业级应用路由管理都能胜任。掌握这些核心概念后,你可以根据项目需求选择合适的路由模式和组织方式。