1、安装
npm install react-router-dom
2、传统路由(组件式路由)
-
核心组件:
<BrowserRouter> + <Routes> + <Route>
-
特点:
- 路由通过 JSX 组件树直接定义
- 数据加载(如 API 请求)通常在组件内部(如
useEffect
)处理 - 适用于简单应用,无需复杂数据预加载的场景
-
示例:
// App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Login from "./page/Login"
import Article from "./page/Article"
import ErrorPage from "../page/ErrorPage"
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />} /> {/* 匹配默认路由 */}
<Route path="/login" element={<Login />} />
<Route path="/about" element={<Article />} />
<Route path="*" element={<ErrorPage />} /> {/* 匹配所有未知路径 */}
</Routes>
</BrowserRouter>
);
}
export default App
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import store from './store'
import { Provider } from 'react-redux'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
)
3、数据路由(Data Router)
-
核心 API:
createBrowserRouter + RouterProvider
-
特点:
- 集中式路由配置:通过 JavaScript 对象定义路由,而非 JSX
- 内置数据流:支持路由级的
loader
(数据预加载)和action
(表单提交处理) - 错误边界:可通过
errorElement
统一处理路由级错误 - 适用于需要复杂数据预加载、服务端渲染(SSR)或静态生成(SSG)的场景
-
示例:
// src/router/index.js
import { createBrowserRouter } from 'react-router-dom'
import Login from "../page/Login"
import Article from "../page/Article"
import ErrorPage from "../page/ErrorPage"
const router = createBrowserRouter([
{
path: "/", // 匹配默认路由
element: <Login />,
errorElement: <ErrorPage />, // 404路由配置方法一
},
// { // 404路由配置方法二
// path: "*",
// element: <ErrorPage />
// },
{
path: "/login",
element: <Login />,
},
{
path: "/article",
element: <Article />
}
])
export default router
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import store from './store'
import { Provider } from 'react-redux'
import { RouterProvider } from 'react-router-dom'
import router from './router'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<RouterProvider router={router} />
</Provider>
)
总结
createBrowserRouter
+RouterProvider
是 React Router v6.4+ 的数据路由 API,用于替代传统的<BrowserRouter>
,提供更强大的数据流控制。- 适用场景:需要预加载数据、统一错误处理或复杂路由逻辑的应用。
- 与传统路由的关系:数据路由是传统路由的功能扩展,两者可结合使用,但推荐新项目直接采用数据路由
4、路由跳转
(1)声明式跳转(Link标签)
import { Link } from "react-router-dom"
function Login() {
return (
<div>
<Link to="/article">跳转到文章列表</Link>
</div>
)
}
export default Login
(2)编程式跳转(useNavigate钩子)
import { useNavigate } from "react-router-dom"
function Login() {
const navigate = useNavigate()
return (
<div>
<button onClick={() => {navigate('/article')}}>跳转到文章列表</button>
</div>
)
}
export default Login
5、路由传参
(1)路径参数传参(Params)
通过 URL 路径传递参数(需提前在路由配置中定义动态段 :params)。
// 路由配置
const router = createBrowserRouter([
{
path: "/article/:name/:age",
element: <Article />
}
])
// 跳转时传递参数
navigate('/article/zhangsan/18')
// 目标组件中获取参数
import { useParams } from 'react-router-dom'
function Article() {
const params = useParams()
const name = params.name
const age = params.age
return (
<div>文章{ name } - { age}</div>
)
}
(2)查询参数传参(Query)
通过 URL 的?key=value形式传递参数
// 跳转时传递参数
navigate('/article?name=zhangsan&age=18')
// 目标组件中获取参数
import { useSearchParams } from "react-router-dom"
function Article() {
const [searchParams] = useSearchParams()
const name = searchParams.get('name')
const age = searchParams.get('age')
return (
<div>文章{ name } - { age}</div>
)
}
(3)状态参数传参(State)
通过state属性传递对象(数据不会暴露在 URL 中)
// 跳转时传递参数
navigate('/article', {
state: {
name: 'zhangsan',
age: 18
}
})
// 目标组件中获取参数
import { useLocation } from "react-router-dom"
function Article() {
const location = useLocation()
const name = location.state.name
const age = location.state.age
return (
<div>文章{ name } - { age}</div>
)
}
6、嵌套路由
- 使用children属性配置路由嵌套关系
- 使用<Outlet />组件配置二级路由渲染位置
- 子路由的 path 无需以 / 开头,会自动与父路径拼接, 以 / 开头会覆盖父路径(不推荐)
// router/index.js
import { createBrowserRouter } from 'react-router-dom'
import Layout from "../page/Layout"
import About from "../page/About"
import Board from "../page/Board"
import ErrorPage from "../page/ErrorPage"
const router = createBrowserRouter([
{
path: "/", // 匹配默认路由
element: <Layout />
},
{
path: "/layout",
element: <Layout />,
children: [ // 嵌套路由
{
path: "about",
element: <About />
},
{
path: "board",
element: <Board />
}
]
}
])
export default router
// page/Layout/index.js
import { Link, Outlet } from "react-router-dom"
function Layout() {
return (
<div>
我是一级路由Layout
<Link to='/layout/about'>关于</Link>
<Link to='/layout/board'>面板</Link>
<Outlet />
</div>
)
}
export default Layout
配置默认二级路由
当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,设置index属性为true
const router = createBrowserRouter([
{
path: "/layout",
element: <Layout />,
children: [ // 嵌套路由
{
index: true,
// path: 'about',
element: <About />
},
{
path: "board",
element: <Board />
}
]
}
])
// page/Layout/index.js
import { Link, Outlet } from "react-router-dom"
function Layout() {
return (
<div>
我是一级路由Layout
<Link to='/layout'>关于</Link>
<Link to='/layout/board'>面板</Link>
<Outlet />
</div>
)
}
export default Layout
7、路由模式
各个主流框架的路由常用的路由模式有俩种,history模式和hash模式,ReactRouter分别由 createBrowerRouter 和 createHashRouter 函数负责创建
对比维度 | BrowserRouter | HashRouter |
---|---|---|
URL 格式 | http://example.com/path (无 # ) | http://example.com/#/path (带 # ) |
底层实现 | 基于浏览器 History API | 基于 window.location.hash |
SEO 友好性 | ✅(需服务端配合) | ❌(哈希内容可能被忽略) |
服务端配置需求 | ✅(需配置重定向到 index.html ) | ❌(无需服务端处理) |
浏览器兼容性 | 现代浏览器 | 所有浏览器(包括旧版 IE) |
适用场景 | 生产环境 SPA(需服务端支持) | 静态托管(如 GitHub Pages) |
代码示例 | createBrowerRouter | createHashRouter |