React基础:路由

124 阅读2分钟

本文总结了在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')

路由声明

  1. 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重定向到某个页面

  1. 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>
  )
}

路由跳转

  1. 声明式:利用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>
  )
}
  1. 函数式:

小于等于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>
}

其他常用工具

  1. 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>
}
  1. 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()
}

参考资料

React Router v6 官方文档