主题
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.jsx
jsx
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 router
jsx
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>
)
}