React-Router V6 使用详解
React-Router 是 React 生态中最流行的路由解决方案之一,V6 版本带来了许多重大改进和简化。本文将全面介绍 React-Router V6 的核心概念、API 和使用方法。
一、React-Router V6 概述
React-Router V6 于 2021 年发布,相比 V5 更简单的 API 设计, 完全支持 React hooks、
、路由配置更加灵活
、移除了 <Switch> 组件,改用 <Routes>
、 相对路径和链接简化
、路由嵌套更直观
二、基本使用
安装
npm install react-router-dom@6
# 或
yarn add react-router-dom@6
核心组件说明
<BrowserRouter>:包裹整个react应用,提供基于 HTML5 history API 的路由管理。<Routes>:替代了旧版本中的<Switch>,用于包裹一组<Route>组件,并根据当前 URL 显示匹配的第一个子<Route>。<Route>:定义路由映射关系path:路由路径element:匹配时渲染的组件(V5 中是component或render)
具体使用(启用全局路由模式)
创建一个react项目,在入口文件(如 index.js 或 main.js),引入BrowserRouter并将应用组件包裹在 BrowserRouter 中。之后在的应用中,使用 Routes 和 Route 组件来定义你的路由结构
main.jsx
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.jsx";
import { BrowserRouter as Router } from "react-router-dom";
createRoot(document.getElementById("root")).render(
<Router>
<App />
</Router>
);
App.jsx
import { Routes, Route } from 'react-router-dom';
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="users" element={<Users />} />
</Routes>
);
}
function Home() {
return (
<h2>Home</h2>
);
}
function About() {
return (
<h2>About</h2>
);
}
function Users() {
return (
<h2>Users</h2>
);
}
通过改变url即可切换不同的组件
三、路由导航
声明式导航
Link 和 NavLink
Link提供了一个声明式的方式来导航到不同的页面。NavLink是Link的一个变体,当其目标路径与当前URL匹配时,可以自动添加样式类(如activeClassName)。
使用 <Link> 和 <NavLink>:
import { Link, NavLink } from 'react-router-dom';
function Navigation() {
return (
<nav>
<Link to="/">Home</Link>
<NavLink
to="/about"
style={({ isActive }) => ({ color: isActive ? 'red' : 'blue' })}
>
About
</NavLink>
</nav>
);
}
<NavLink> 可以感知当前是否处于激活状态。
编程式导航
使用useNavigatehook返回一个函数,使用该函数在组件内部进行编程式导航。
使用 useNavigate hook:
import { useNavigate } from 'react-router-dom';
function LoginButton() {
const navigate = useNavigate();
const handleLogin = () => {
// 跳转到指定路径
navigate('/dashboard');
// 替换当前历史记录
// navigate('/dashboard', { replace: true });
// 带状态跳转
// navigate('/dashboard', { state: { from: 'login' } });
};
return <button onClick={handleLogin}>Login</button>;
}
四、动态路由与参数
路径参数
假设你有一个用户详情页面,并且想要通过用户 ID 来访问该用户的详情信息,你可以这样做:
<Route path="users/:id" element={<UserDetail />} />
在这个例子中,:id 是一个动态参数。要访问这个参数,在你的 UserDetail 组件内可以使用 useParams 钩子来获取这个参数:
import { useParams } from 'react-router-dom';
function UserDetail() {
const { id } = useParams();
console.log(id)
return <div>User ID: {id}</div>;
}
输入
http://localhost:5173/users/123
输出
123
通过查询参数传递
对于查询参数(即 URL 中的键值对,如 ?name=value&mode=edit),可以使用 useSearchParams 钩子来获取这些参数:
import { useSearchParams } from 'react-router-dom';
function ComponentWithQueryParams() {
let [searchParams] = useSearchParams();
let name = searchParams.get('name');
let mode = searchParams.get('mode');
return (
<div>
<p>Name: {name}</p>
<p>Mode: {mode}</p>
</div>
);
}
function App() {
return (
<Routes>
<Route path="/path" element={<ComponentWithQueryParams />} />
</Routes>
);
}
为了导航到包含查询参数的路径,你可以使用 useNavigate 或者 <Link> 组件,并将查询参数作为对象传递给 to 属性:
import { useNavigate } from 'react-router-dom';
function NavigateButton() {
let navigate = useNavigate();
function handleClick() {
navigate('/path', { search: '?name=value&mode=edit' });
}
return <button onClick={handleClick}>Go</button>;
}
五、嵌套路由
从 react-router-dom v6 开始,定义嵌套路由的方式有所变化,主要是通过 <Routes> 和 <Route> 组件来实现的。下面是一个简单的例子,演示如何设置嵌套路由:
假设你有一个应用布局如下:
- 主页
- 用户列表页
- 单个用户的详情页
App中路由配置
在这个例子中,Users 组件将会渲染用户列表,而 UserProfile 组件会渲染单个用户的详情。:id 是一个动态参数,用于标识不同的用户。
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './Home';
import Users from './Users';
import UserProfile from './UserProfile';
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<Users />}>
{/* 嵌套路由 */}
<Route path=":id" element={<UserProfile />} />
</Route>
</Routes>
</Router>
);
}
在父路Users由中使用 <Outlet>
为了让嵌套路由工作,父级路由组件(本例中的 Users 组件)需要使用 Outlet 来指定子路由应该在哪里渲
import { Outlet } from 'react-router-dom';
function Users() {
return (
<div>
<h1>用户列表</h1>
{/* 子路由将在这里渲染 */}
<Outlet />
</div>
);
}
索引路由
索引路由是当父路由路径匹配时默认渲染的子路由
当进入访问 / 时,之间导航到<Route index element={} />
<Route path="/" element={<Users />}>
<Route index element={<Like />} />
<Route path="/stats" element={<Like />} />
</Route>
六、重定向
在 react-router-dom 中实现**重定向(Redirect)**是一个常见的需求,比如用户未登录时跳转到登录页、页面路径变更后的跳转、或者路由匹配失败时跳转到 404 页面等。
在 react-router-dom v6 及以上版本中,不再使用 Redirect 组件(v5 中可用),而是推荐使用新的方式:useNavigate 钩子 或 <Navigate> 组件。
使用 <Navigate> 组件:
import { Navigate } from 'react-router-dom';
function ProtectedRoute({ isLoggedIn, children }) {
if (!isLoggedIn) {
return <Navigate to="/login" replace />;
}
return children;
}
参数说明:
to:要跳转的目标路径,可以是字符串或对象。replace:是否替换当前历史记录,默认为false。设置为true时,用户无法通过“返回”按钮回到上一页。
使用 useNavigate 钩子(适用于逻辑跳转,如点击按钮后跳转)
import { useNavigate } from 'react-router-dom';
function LoginPage() {
const navigate = useNavigate();
const handleLogin = () => {
// 模拟登录成功
const success = true;
if (success) {
navigate('/dashboard'); // 跳转到首页
}
};
return (
<div>
<h2>登录页面</h2>
<button onClick={handleLogin}>登录</button>
</div>
);
}