React Router基础 #
一、React Router概述 #
1.1 什么是React Router #
React Router 是 React 生态中最流行的路由库,用于构建单页应用(SPA)的路由系统。
1.2 安装 #
bash
npm install react-router-dom
1.3 核心组件 #
| 组件 | 说明 |
|---|---|
| BrowserRouter | 路由容器 |
| Routes | 路由配置容器 |
| Route | 单个路由规则 |
| Link | 导航链接 |
| Navigate | 编程式导航 |
二、基本使用 #
2.1 路由配置 #
javascript
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/users" element={<Users />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
2.2 导航链接 #
javascript
import { Link, NavLink } from 'react-router-dom';
function Navbar() {
return (
<nav>
{/* 普通链接 */}
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
{/* 导航链接(带激活状态) */}
<NavLink
to="/users"
className={({ isActive }) => isActive ? 'active' : ''}
>
用户
</NavLink>
</nav>
);
}
2.3 嵌套路由 #
javascript
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="users" element={<Users />}>
<Route index element={<UserList />} />
<Route path=":id" element={<UserDetail />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
);
}
function Layout() {
return (
<div>
<nav>
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
<Link to="/users">用户</Link>
</nav>
<main>
<Outlet />
</main>
</div>
);
}
function Users() {
return (
<div>
<h2>用户列表</h2>
<Outlet />
</div>
);
}
三、路由参数 #
3.1 动态参数 #
javascript
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<UserDetail />} />
<Route path="/posts/:postId/comments/:commentId" element={<Comment />} />
</Routes>
</BrowserRouter>
);
}
function UserDetail() {
const { id } = useParams();
return <div>用户ID: {id}</div>;
}
function Comment() {
const { postId, commentId } = useParams();
return (
<div>
文章ID: {postId}
评论ID: {commentId}
</div>
);
}
3.2 查询参数 #
javascript
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams();
const query = searchParams.get('q') || '';
const page = searchParams.get('page') || '1';
const category = searchParams.get('category') || 'all';
const handleSearch = (newQuery) => {
setSearchParams({ q: newQuery, page: '1' });
};
const handlePageChange = (newPage) => {
setSearchParams(prev => {
prev.set('page', newPage);
return prev;
});
};
return (
<div>
<input
value={query}
onChange={(e) => handleSearch(e.target.value)}
/>
<p>搜索: {query}</p>
<p>页码: {page}</p>
<p>分类: {category}</p>
</div>
);
}
3.3 State传递 #
javascript
function UserList() {
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
return (
<ul>
{users.map(user => (
<li key={user.id}>
<Link
to={`/users/${user.id}`}
state={{ from: 'list', user }}
>
{user.name}
</Link>
</li>
))}
</ul>
);
}
function UserDetail() {
const location = useLocation();
const { from, user } = location.state || {};
return (
<div>
<p>来源: {from}</p>
<p>用户: {user?.name}</p>
</div>
);
}
四、编程式导航 #
4.1 useNavigate #
javascript
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const navigate = useNavigate();
const handleSubmit = async (credentials) => {
const success = await login(credentials);
if (success) {
navigate('/dashboard');
// 或带参数
navigate('/dashboard', { replace: true });
// 或返回上一页
navigate(-1);
}
};
return (
<form onSubmit={handleSubmit}>
{/* ... */}
</form>
);
}
4.2 Navigate组件 #
javascript
function ProtectedRoute({ children }) {
const { user } = useAuth();
if (!user) {
return <Navigate to="/login" replace />;
}
return children;
}
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
</Routes>
</BrowserRouter>
);
}
五、路由守卫 #
5.1 权限控制 #
javascript
function RequireAuth({ children }) {
const { user } = useAuth();
const location = useLocation();
if (!user) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
}
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/admin"
element={
<RequireAuth>
<AdminPanel />
</RequireAuth>
}
/>
</Routes>
</BrowserRouter>
);
}
5.2 角色权限 #
javascript
function RequireRole({ children, allowedRoles }) {
const { user } = useAuth();
if (!user) {
return <Navigate to="/login" replace />;
}
if (!allowedRoles.includes(user.role)) {
return <Navigate to="/forbidden" replace />;
}
return children;
}
function App() {
return (
<Routes>
<Route
path="/admin"
element={
<RequireRole allowedRoles={['admin']}>
<AdminPanel />
</RequireRole>
}
/>
</Routes>
);
}
六、404处理 #
6.1 捕获所有路由 #
javascript
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
function NotFound() {
return (
<div>
<h1>404</h1>
<p>页面不存在</p>
<Link to="/">返回首页</Link>
</div>
);
}
七、路由配置对象 #
7.1 useRoutes #
javascript
import { useRoutes } from 'react-router-dom';
const routes = [
{
path: '/',
element: <Layout />,
children: [
{ index: true, element: <Home /> },
{ path: 'about', element: <About /> },
{
path: 'users',
children: [
{ index: true, element: <UserList /> },
{ path: ':id', element: <UserDetail /> }
]
}
]
}
];
function App() {
const element = useRoutes(routes);
return element;
}
7.2 createBrowserRouter #
javascript
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([
{
path: '/',
element: <Layout />,
children: [
{ index: true, element: <Home /> },
{ path: 'about', element: <About /> },
{
path: 'users/:id',
element: <UserDetail />,
loader: async ({ params }) => {
return fetch(`/api/users/${params.id}`);
}
}
]
}
]);
function App() {
return <RouterProvider router={router} />;
}
八、最佳实践 #
8.1 路由结构组织 #
javascript
// routes/index.jsx
export const routes = [
{
path: '/',
element: <Layout />,
children: [
{ index: true, element: <Home /> },
...userRoutes,
...adminRoutes
]
}
];
// routes/userRoutes.jsx
export const userRoutes = [
{
path: 'users',
children: [
{ index: true, element: <UserList /> },
{ path: ':id', element: <UserDetail /> }
]
}
];
8.2 懒加载路由 #
javascript
import { lazy, Suspense } from 'react';
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<BrowserRouter>
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
九、总结 #
| 要点 | 说明 |
|---|---|
| BrowserRouter | 路由容器 |
| Routes/Route | 路由配置 |
| Link/NavLink | 导航链接 |
| useParams | 获取动态参数 |
| useSearchParams | 获取查询参数 |
| useNavigate | 编程式导航 |
核心原则:
- 使用 BrowserRouter 包裹应用
- 使用 Routes 和 Route 配置路由
- 使用 Link 进行导航
- 使用 useParams 获取路由参数
最后更新:2026-03-26