哈喽~小伙伴们,简单说一下,本篇文章主要介绍react-router-dom 6.x的版本使用(稍带着跟之前的版本做下对比),如果你现在采用的是6.x的版本,那么可以参照这儿进行开发了(ps: 代码居多,适合实战),希望对你有所帮助~~
1. 直接匹配路径,不再需要exact字段进行精确匹配,减少歧义,也无需注意顺序
2. 嵌套路由 里层渲染使用 <Outlet />
<Outlet/>的出现帮我们节省了很多代码逻辑避免了多个< Routes />,主要用于子组件显示,作用类似于Vue中的router-view
3. 路由跳转
import { useNavigate } from 'react-router-dom'
// 获取
const navigate = useNavigate()
// 跳转
navigate('/login')
4. 路由使用,包含获取路由参数
// App.tsx
import { Routes, Route } from 'react-router-dom'
...
function App() {
return (
<Routes>
<Route path='/' element={<Applayout/>}>
<Route index element={<Home/>} />
<Route path='/user' element={<User/>} />
<Route path='/user/detail/:id' element={<Detail/>} />
</Route>
<Route path='/login' element={<Login/>} />
</Routes>
)
}
// User.tsx
import React from 'react'
import { Link } from 'react-router-dom'
function User() {
return (
<div>
user
<ul>
<li><Link to={'/user/detail/1}>用户1</Link>
<li><Link to={'/user/detail/2}>用户2</Link>
<li><Link to={'/user/detail/3}>用户3</Link>
<li><Link to={'/user/detail/4}>用户4</Link>
</ul>
</div>
)
}
// detail.tsx 获取路由参数
import { useParams } from 'react-router-dom'
function Detail() {
const params = useParams()
return (
<div>{params.id}</div>
)
}
5. 集中式路由渲染
- 这种写法复杂冗余,改为使用useRoutes这个hook代替此写法
// App.tsx
import routes from '../routes'
import { useRoutes } from 'react-router-dom'
const App = () => {
const routing = useRoutes(routes)
return (
<>{routing}</>
)
}
// routes/index.tsx
const routes = [
{ element: <Home />, path: '/', name: '首页' },
{
path: '/admin',
name: '管理页',
children: [
{
path: '/admin/sub-page1',
name: '一级页面',
element: <Courses />,
},
]
},
]
6. 页面懒加载
- 可以优化应用启动的速度
- 只加载当前页面所需组件,不会全量加载
// router/index.tsx
import { lazy } from 'react'
const Home = lazy(() => import('../pages/Home'))
const router = [
{
path: '/home',
element: <Home />
}
]
// App.tsx
import { Suspense } from 'react'
import { useRoutes } from 'react-router-dom'
function App() {
return (
<Suspense fallback={<>loading</>}>
{useRoutes(router)}
</Suspense>
)
}
7. 避免闪屏
- 公共的布局模块不进行懒加载,而是正常引入(预加载)
- suspense
- Suspense 让组件遇到异步操作时进入“悬停”状态,等异步操作有结果时再回归正常状态。
- 异步操作分为两类:1. 异步加载代码 2. 异步加载数据
- 使用优化,代码如下:
import AppLayout from '../AppLayout' // 此处不进行懒加载
const Home = lazy(() => import('../pages/Home')) // 此处需要懒加载
const lazyLoad = (children: ReactNode): ReactNode => {
return <Suspense fallback={<>loading</>}>
{children}
</Suspense>
}
const router: RouteObject[] =[
{
path: '/',
element: <AppLayout/>, // 此处不进行懒加载
children: [
{
path: 'home',
element: lazyLoad(<Home /> // 此处需要懒加载
}
]
}
]
8. 获取当前页面路径
import { useLocation } from 'react-router-dom'
function Axx () {
const location = useLocation()
console.log(location.pathname)
}
9. 参数的获取
// localhot:8080/use/list?name=wfy&age=25
// 如何获取后面的参数?
import { useSearchParams } from 'react-router-dom'
function User() {
const [params, _] = useSearchParams()
console.log(params.get('name'))
console.log(params.getAll('age'))
}
10. 路由监听
- 目的:实现类似于vue的路由守卫功能,主要利用react hooks实现,具体实现如下:
// App.tsx
import React from 'react'
import Access from './Access'
...
function App () {
const location = useLocation()
const { canAccess, setCanAccess } = useState(false)
useEffect(() => {
console.log(location.pathname, 'center')
return () => {
console.log(location.pathname, 'leave')
}
}, [canAccess, location.pathname])
return(
<>
<ul>
<li>
<Link to={'/'}>Home</Link>
<Link to={'/user'}>user</Link>
<Link to={'/dog'}>dog</Link>
</li>
</ul>
<Routes>
<Route path='/' element={<Home/>} />
<Route path='/user' element={<User/>} />
<Route path='/dog' element={
<Access canAccess={canAccess} children={<Dog />} />
} />
</Routes>
</>
)
}
// Access.tsx
import React, {ReactNode} from 'react
interface IProps {
canAccess: boolean;
children?: ReactNode;
}
function Access({ canAccess, children }: Iprops) {
if (!canAccess) {
return null
}
return <> {children} </>
}