主题
React Router
介绍
React Router 是一个用于处理路由的库,它提供了一套用于处理路由的组件和 API,使得在 React 应用中实现路由功能更加方便和灵活。
安装
bash
npm i react-router-dom@6详细说明
v17 -> react-router-dom@5 v18 -> react-router-dom@6
项目搭建
bash
/src
/router
index.jsx
App.jsx
main.jsxjsx
import { createHashRouter } from 'react-router-dom'
import React, { Suspense } from 'react'
import Home from '../views/Home.jsx'
const About = React.lazy(() => import('../views/About.jsx'))
const router = createHashRouter([
{
path: '/',
element: <Home />,
},
{
path: '/about',
element: (
<Suspense fallback={<div>Loading...</div>}>
<About />
</Suspense>
),
},
])
export default routerjsx
import { RouterProvider } from 'react-router-dom'
import router from './router'
function App() {
return <RouterProvider router={router}></RouterProvider>
}
export default App路由懒加载
如上,使用 React.lazy 引入组件,还可以使用 Suspense 包裹,指定 fallback 为加载提示组件。
路由模式
Hash 模式
jsx
import { createHashRouter } from 'react-router-dom'
const router = createHashRouter([
// ...
])HTML5 模式
jsx
import { createBrowserRouter } from 'react-router-dom'
const router = createBrowserRouter([
// ...
])Memory 模式
jsx
import { createMemoryRouter } from 'react-router-dom'
const router = createMemoryRouter(routes, {
// ...
})路由导航
声明式
jsx
import { Link } from 'react-router-dom'
function Home() {
return (
<div>
<h1>Home</h1>
<Link to="/about">关于页</Link>
</div>
)
}
export default Home编程式
jsx
import { useNavigate } from 'react-router-dom'
function Home() {
const navigate = useNavigate()
return (
<div>
<h1>Home</h1>
<button onClick={() => navigate('/about')}>关于页</button>
</div>
)
}
export default Home路由传参 & 接参
searchParams
jsx
<Link to={`/user?id=12&name=vfanlee`}>User</Link>jsx
import { useSearchParams } from 'react-router-dom'
const [params] = useSearchParams()
const id = params.get('id')
const name = params.get('name')params
jsx
{
path: '/user/:id/:name',
element: <User />
}jsx
import { useParams } from 'react-router-dom'
const params = useParams()
const id = params.id
const name = params.name嵌套路由
- 在路由配置文件中通过
children属性配置子路由 - 在父组件中通过
<Outlet>组件渲染子路由
jsx
{
path: '/',
element: <Layout />,
children: [
{
path: '/home',
element: <Home />
},
{
path: '/about',
element: <About />
}
]
}jsx
import { Outlet } from 'react-router-dom'
function Layout() {
return (
<>
<h1>Layout</h1>
<Outlet />
</>
)
}
export default Layout默认路由
嵌套路由时,指定某个子路由为默认路由,可通过 index: true 指定默认路由:
jsx
{
path: '/',
element: <Layout />,
children: [
{
index: true,
element: <Home />
},
{
path: '/about',
element: <About />
}
]
}亦或者,定义 path 为空字符串:
jsx
{
path: '/',
element: <Layout />,
children: [
{
path: '',
element: <Home />
},
{
path: '/about',
element: <About />
}
]
}404 路由
jsx
{
path: '*',
element: <NotFound />
}路由激活
在 React Router v6 中,获取当前激活路由的最佳方式是使用 <NavLink> 组件或 useLocation 钩子。
使用 <NavLink> 自动高亮当前路由
这是最简单的方式,<NavLink> 会自动为当前激活的链接添加 active 类(可以自定义)。
jsx
import { NavLink } from 'react-router-dom'
function Navbar() {
return (
<nav>
<NavLink to="/home" className={({ isActive }) => (isActive ? 'active' : '')}>
Home
</NavLink>
<NavLink to="/about" className={({ isActive }) => (isActive ? 'active' : '')}>
About
</NavLink>
</nav>
)
}你可以在 CSS 里定义 .active 来控制高亮样式:
css
.active {
color: #00dc82;
font-weight: bold;
}使用 useLocation 钩子手动判断当前路径
如果你不使用 <NavLink>,可以用 useLocation 获取当前路径名,再手动判断:
jsx
import { useLocation, Link } from 'react-router-dom'
function Navbar() {
const location = useLocation()
return (
<nav>
<Link to="/home" className={location.pathname === '/home' ? 'active' : ''}>
Home
</Link>
<Link to="/about" className={location.pathname === '/about' ? 'active' : ''}>
About
</Link>
</nav>
)
}注意:location.pathname 是完整路径,不带 query 或 hash。
带参数或嵌套路由
如果你用的是动态路径,比如 /users/:id,可以使用 useMatch 来匹配当前路由:
jsx
import { useMatch, Link } from 'react-router-dom'
function Navbar() {
const match = useMatch('/users/:id')
return (
<Link to="/users/123" className={match ? 'active' : ''}>
User Detail
</Link>
)
}