react-router-dom v6 路由用法

1,182 阅读2分钟

哈喽~小伙伴们,简单说一下,本篇文章主要介绍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} </>
}