React 路由

这是我做的一个基于UmiJS的任务待办桌面应用,欢迎大家给我star

这是我做的一个博客管理系统,该系统在路由拦截这一块的做的非常好,欢迎大家star

路由

路由基本功能

  1. 保证视图和url的同步

history

history可以用来兼容在不同浏览器、不同环境下对历史记录的管理。

history分为三类,分别是browserHistory、hashHistory和memoryHistory。browserHistory利用的是H5中的history接口hashHistory利用的是history中的location属性的hash

browserHistory采用push和replace(编程式路由)来实现url的改变,这两个方法分别封装了history的pushStatereplaceState方法。这两个方法都会改变当前的url,但不会刷新页面。还有例如go()、back()、forward()等方法。这些方法都会触发popState事件,所以在browseHistory采用手动触发popState的方式来实现对url改变的监听

hashHistory通过区分history对象中的location属性中包含的hash字段来渲染不同的组件。

React-Router的实现原理

React-Router是建立在history之上的,history会监听浏览器地址栏的变化,并解析url转化为location对象,然后router匹配到对应的路由,最后渲染对应的组件

Router负责根据当前的url来渲染相应的组件
Route根据当前的url与自身的path属性进行匹配,匹配成功就渲染对应的组件

何如配置React-Router实现路由切换

  • 使用<Route>组件
    路由匹配是通过比较的path属性与当前的pathname来实现的。可以给<Route>组件加上 exact 属性来实现路由精准匹配。
<Route path="/home" component={Home} />
  • <Switch>和<Route>
    因为<Route>采用的是模糊匹配,所以可能一次会匹配到多个路由,<Switch>的作用就是控制每次只匹配一个路由。在<Route>外层包裹<Switch>表示只会匹配到第一个匹配的<Route>。
<Swicth>
  <Route path="/home" component={Home} />
  <Route path="/about" component={About} />
</Switch>
  • <Link>、<NavLink>和<Redirect>
    <Link>就是渲染在页面中的路由跳转链接,<Link>组件将被渲染为一个<a>标签。
<Link to="/home">Home</Link>
// 在页面中被渲染为:<a href="/home">Home</a>

<Link>的跳转行为只会触发相匹配的组件的内容更新,而不会重新渲染整个页面。

<NavLink>是一种特殊的<Link>,当它的to属性与当前地址匹配时,可以将其定义为active状态。

<Redirect>组件用于重定向路由。

<Redirect from="/users/:id" to="/user/profile/:id">

从/users/:id 转到 /user/profile/:id。

Link和a标签的区别

从最终渲染的DOM来看,两者都是链接。区别在于:<Link>是实现路由跳转的链接,一般配合
<Route>使用,<Link>的跳转行为只触发了相匹配的<Route>对应的页面内容更新,而不会刷新整个页面。

我个人的理解:因为React是一个单页面应用,在每次进行路由切换时都是在一个HTML文件中发生的,这个HTML文件在页面首次加载时就已经下载下来了,使用<Link>在路由切换时不会重新去请求一个HTML文件;而<a>在每次跳转时都会加载对应页面的HTML文件,在某些网速慢得情况下会出现空白页,导致用户体验不好。<Link>在通过阻止<a>标签的默认事件,然后根据href(即<Link>的to属性)进行页面跳转。

Router如何获取URL的参数和历史对象

获取URL参数:

  1. get传值。通过props.location.search取值。
  2. 动态路由传值。在V6之前的版本可以使用props.match.params.属性值来取值;V6
    版本可以通过useParams和useSearchParams钩子函数来取值。

获取历史对象:

  1. useHistory钩子函数获取历史对象。
  2. props.history获取历史对象。

路由拦截(路由守卫)

const isAuth = () => {
  // 判断是否有token字段
  return localStorage.getItem("token")
}

// 实现路由拦截
<Route path="/cart" render={()=>{
  return isAuth() ? <Cart /> : <Redirect to="/login">
}} />

Router V6

V6版本的一些更改

  1. <Switch>重命名为<Routes>
  2. <Route>的特性变更(component/render被element替代)
  3. 嵌套路由变得更简单
  4. 使用<useNavigate>代替<useHistory>
  5. 使用<useRoutes>代替react-router-config
  6. 更小的体积
// history模式
<BrowserRouter>
  {/* 路由入口:指定跳转到哪一个组件,to用来配置路由地址 */}
  <Link to='/'>首页</Link>
  <Link to='/about'>关于</Link>
  <Link to='/login'>登录</Link>
  {/* 路由出口:路由对应的组件会在这里进行渲染 */}
  <Routes>
    {/* 指定路径和组件的对应关系,用于指定导航链接,完成路由匹配 */}
    <Route path="/" element={<Home />}></Route>
    <Route path="/about" element={<About />}></Route>
    <Route path="/login" element={<Login />}></Route>
  </Routes>
</BrowserRouter >
  • Link:路由入口,用于指定导航链接,完成路由跳转,最终渲染为a标签
  • Routes:路由出口,路由对应的组件在Routes中进行渲染
  • Route:指定路由地址与组件的对应关系,用于指定导航链接,完成路由匹配
  • BrowserRouter:history模式

编程式导航

Router v6通过useNavigate钩子函数实现编程式导航

import { useNavigate } from 'react-router-dom'
// 指定钩子函数得到跳转函数
const navigate = useNavigate()
// 执行跳转函数,跳转到about页
navigate('/about')   // 相当于push
navigate('/about', { replace: true })   // 相当于replace
navigate(-1)    // 相当于back
navigate(1)     // 相当于forward
navigate(-2)    // 相当于go

传参

Router v6有两种传参方式

  1. searchParams传参
// 传参:
navigage('/about?id=1001')
// 取参:
let [params] = useSearchParams()
let id = params.get('id')

params是一个对象,里面包含很多方法:get、append、delete、forEach等,可以对传来的参数进行操作。

  1. params传参
// 传参:
navigage('/about/1001')
// 取参:
let params = useParams()
let id = params.id

第二种方法的参数就是一个参数对象。

嵌套路由

  1. 定义嵌套路由声明
{/* 指定路径和组件的对应关系,用于指定导航链接,完成路由匹配 */}
<Route path="/" element={<Home />}>
  {/* 定义二级路由 */}
  <Route path='board' element={<Board />}></Route>
  <Route path='article' element={<Article />}></Route>
</Route>
  1. 使用指定二级路由出口
    然后再Home组件中配置二级路由出口。
import { Outlet } from 'react-router-dom'
{/* 二级路由出口 */}
<Outlet></Outlet>

配置默认路由

使用index关键字配置默认路由

<Route index element={<Board />}></Route>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值