本文总结了在React中使用React Router(v6)进行路由开发的基础知识,包括路由模式、路由声明、路由跳转等等......
两种路由模式
history模式
- 根路由是BrowserRouter
- 页面url的形式是:
域名/path - history对应的创建方式:createBrowserHistory
- 改变路由的本质方式:
- window.history.pushState
- window.history.replaceState
- 监听路由的本质方式:window.addEvenetListener('popstate')
hash模式
- 根路由是HashRouter
- 页面url的形式是:
域名/#/path - history对应的创建方式:createHashHistory
- 改变路由的本质方式:window.location.hash
- 监听路由的本质方式:window.addEventListener('hashchange')
路由声明
Switch+Route在jsx中声明路由匹配规则
import { Switch, Route } from 'react-router-dom'
import Page1 from './page1'
import Page2 from './page2'
function App() {
return (
<Switch>
<Route path='/page1' element={Page1} />
<Route path='/page2' elemnent={Page2} />
<Redirect from='/*' to='/page1' />
</Switch>
)
}
如果Switch找不到匹配的路由,又不想让页面空白,就可以使用Redirect重定向到某个页面
useRoutes+routeConfig在ts中声明路由匹配规则
常用的参数
- path:url路径
- element:需要渲染的组件
- errorElement:捕获到异常后兜底渲染某个指定的组件
import { RouteObject, useRoutes } from 'react-router-dom'
import Page1 from './page1'
import Page2 from './page2'
const routes: RoutObject[] = [
{
path: '/page1',
element: <Page1 />,
errorElement: <ErrorPage />
},
{
path: '/page2',
element: <Page2 />,
errorElement: <ErrorPage />
},
// 匹配不到路由时兜底展示
{
path: '/*',
element: <Page1 />,
errorElement: <ErrorPage />
}
]
function App() {
return (
<div>
{useRoutes(ruotes)}
</div>
)
}
路由跳转
- 声明式:利用
Link或者NavLink进行跳转
import { NavLink } from 'react-router-dom'
function Page1() {
return (
<div>
<h1>page1</h1>
<NavLink to='/page2'>click here jump to page2</NavLink>
</div>
)
}
- 函数式:
小于等于v5版本:利用history对象进行跳转
- 无需通过state传递参数时,直接传入字符串
pathname即可 - 需要通过state传递参数时,传入对象
import { useHistory } from 'react-router-dom'
function Page1() {
const history = useHistory()
function gotoPage2() {
history.push('/page2')
}
function gotoPage3() {
history.push({
pathname: '/page3',
state: {
name: 'qqq'
}
})
}
return <div>page1</div>
}
v6版本:利用navigate进行跳转
- 第一个参数为字符串pathname
- 第二个参数为option
import { useNavigate } from 'react-router-dom'
function Page1() {
const navigate = useNavigate()
function gotoPage3() {
navigate('/page3', {
state: {
name: 'qqq'
})
}
return <div>page1</div>
}
其他常用工具
useLocation从路由中读取state
路由跳转携带state时,目标组件可以通过location.state进行读取
import { useLocation } from 'react-router-dom'
function Page3() {
const location = useLocation()
const { name } = (location?.state || {}) as { name?: string }
return <h2>{name}</h2>
}
useParams从url中读取动态参数
import { RouteObject, useRoutes } from 'react-router-dom'
import Page1 from './page1'
import Page2 from './page2'
const routes: RoutObject[] = [
{
path: '/page1/:id',
element: <Page1 />
},
{
path: '/page2',
element: <Page2 />
}
]
如果路由对象的pathname里面包含动态参数,可以通过useParams读取
function Page1() {
// ts自动推断id的类型为string | undefined
const { id } = useParams()
}