【React】react-router-dom

2023-11-16


  • React实现页面路由的模块:react-router-dom
  • 在 React Router 中有三种类型的组件:路由器组件,路由匹配组件,导航组件。这些组件都来自于 react-router-dom

1 路由器组件:< HashRouter > < BrowserRouter >

对于每一个 React Router 应用来说,都应该有一个路由器组件,它们会为应用创建一个专用的 history 对象。
针对 Web 项目,react-router-dom 提供了 <BrowserRouter><HashRouter>

主要区别:

  • BrowserRouter 和 HashRouter 都可以实现前端路由的功能
  • BrowserRouter 实现的是单页面的路由切换
  • HashRouter 实现的是全局路由切换

从原理上:

  • HashRouter在路径中包含了#,相当于HTML的锚点定位。(# 符号的英文叫hash,所以叫HashRouter,和散列没关系哦)
  • 而BrowserRouter使用的是HTML5的新特性History,没有HashRouter(锚点定位)那样通用,低版本浏览器可能不支持。

从用法上:

  • BrowserRouter进行组件跳转时可以传递任意参数实现组件间的通信,
  • HashRouter不能(除非手动拼接URL字符串),因此一般配合Redux使用,实现组件间的数据通信。

其实就是路由的hash和history两种模式,并且这两个组件是路由的容器,必须在最外层。

<HashRouter>
      ...
</HashRouter>


<BrowserRouter>
      	...
</BrowserRouter>

2. 路由

2.1 < Route >

  • 路由匹配是通过比较 <Route> 组件的 path 属性和当前地址的 pathname 实现的

  • 如果匹配则渲染当前路由组件的内容,如果不匹配则渲染 null。

  • 注意:没有提供 path 属性的 <Route> 组件将总是匹配。


2.1.1 < Route element >

  • Route的 render 或 component 改为 element
import Profile from './Profile';

// v5
<Route path=":userId" component={Profile} />
<Route
  path=":userId"
  render={routeProps => (
    <Profile routeProps={routeProps} animate={true} />
  )}
/>


// v6
<Route path=":userId" element={<Profile />} />
<Route path=":userId" element={<Profile animate={true} />} />
<Route path=":userId" element={<Profile animate={true} /> />

function Profile({ animate }) {
	const params = useParams();
	const location = useLocation();
}

通过这种形式:
1. 可以向组件传 props,如上面的 animate={true}
2. 因为有了 hook 的出现,所以不必再通过 renderProps 向组件传递路由的一些 props,我们可以通过useParams、useLocation 就可以拿到这些信息
  • v6 Route 的 children 是用于嵌套路由
<BrowserRouter>
	<Routes>
		<Route path="/" element={<Home />} />
        <Route path="/users" element={<Users />}>
			<Route path="me" element={<OwnUserProfile />} />
			<Route path=":id" element={<UserProfile />} />
        </Route>
	</Routes>
</BrowserRouter>

那么我们要显示 OwnUserProfile 组件的话通过/users/me 就可以定位到了,这看起来相当的直观

2.1.2 < Route path >

v6 简化了 path 的格式,只支持两种动态占位符。

  • :id 样式参数
  • *通配符,只能在path的末尾使用,如 users / *
正确的格式:
path = '/groups'
path = '/groups/admin'
path = '/users/:id'
path = '/users/:id/messages'
path = '/files/*' // 通配符放在末尾
path = '/files/:id/*'
path = '/files-*'

错误的格式:
path = '/users/:id?' // ? 不满足上面两种格式
path = '/tweets/:id(\d+)' // 有正则,不满足上面两种格式
path = '/files/*/cat.jpg'// 通配符不能放中间

2.1.3 < Route index >

index 即表示是否是主路由,如果设置为 true 的话不能有 children

<Routes>
	<Route element={<Layout />}>
		<Route index element={<Home />} />
        <Route path="about" element={<About />}/>
         ...
	</Route>
</Routes>

2.1.4 < Outlet >

<Outlet/> 的作用类似插槽,用于匹配子路由的 element

function App() {
  return (
      <div>
        <BrowserRouter>
          <Routes>
              <Route exact path={'/'} element={<Login />}/>
              <Route path={'/login'} element={<Login />}/>
              匹配到/index里面开始渲染<PrivateRoute/> 组件
              <PrivateRoute/> 返回<Outlet>相当于 开始渲染当前路由的子路由
              <Route path={'/index'} element={<PrivateRoute/>}>
              		即开始渲染<Layoutdemo/>组件 
                    <Route path={'/index'} element={<Layoutdemo/>}>
                        <Route path={'/index/goods'} element={<Goods/>}/>
                        <Route path={'/index/addgoods'} element={<AddGoods/>}/>
                        <Route path={'/index/category'} element={<Category/>}/>
                    </Route>
              </Route>
          </Routes>
        </BrowserRouter>
      </div>
  );
}


let jian = () =>{   //判断用户登录信息是否存在token 存在返回true 跳进主页面
    const token = sessionStorage.getItem('token');
    return token ? true : false;
}
const PrivateRoute = () => {
    return jian() ? <Outlet/> : <Navigate to={'/login'}/>
}


所有路由的定义放在最外边的组件里面 层次清楚

2.1.5 useRoutes()

上面我们都是把 Route 作为 Routes 的 children

function App() {
  return (
    <Routes>
      <Route path='/' element={<Layout />}>
        <Route path='auth/*' element={<Auth/> } />
        <Route path='basic/*' element={<Basic/> } />
      </Route>
    </Routes>
  )
}

我们还可以通过useRoutes生成对应的 element 这种配置项让我们可以清晰地看出路由的嵌套结构

import  { useRoutes } from 'react-router-dom'
function App() {
  const element = useRoutes([
    {
      path: '/',
      element: <Layout />,
      children: [
        {
          path: 'auth/*',
          element: <Auth/>
        },
        {
          path: 'basic/*',
          element: <Basic/>
        }
      ]
    }
  ])
  return (
     {element}
  )
}

2.2 路由:< Switch >全部改为< Routes >

该顶级组件将被重命名。但是,其功能大部分保持不变。

<Switch>

  • <Switch> 组件用于给 <Route> 组件分组,可以将一组 <Route> 组件嵌套在 <Switch> 组件中。
  • <Route> 组件通过比较它的 path 属性和当前地址来判断是否渲染它的内容,所以就会存在多个 <Route> 匹配成功且都渲染它们内容的情况。为了避免这样的情况,<Switch> 组件就起了作用,它会迭代当中的 <Route> 组件,并选出第一个匹配的 <Route> 来渲染
// v5
<Switch>
  <Route exact path='/' component={Home} />
  <Route path='/about' component={About} />
  <Route path='/contact' component={Contact} />
  {/* when none of the above match, <NoMatch> will be rendered */}
  <Route component={NoMatch} />
</Switch>

<Switch>
    <Route exact path="/"><Home /></Route>
    <Route path="/profile"><Profile /></Route>
</Switch>


// v6
<Routes>
    <Route path="/" element={<Home />} />
    <Route path="profile/*" element={<Profile />} />
</Routes>

2.3 导航 < Link >和< NavLink >

两者都是跳转路由,NavLink的参数更多些。

2.3.1 < Link to >

  • 在v5中,如果 to 不以 / 开头的话会让人有点迷,因为这取决于当前的 URL。

  • 比如当前 URL 是/user, 那么<Link to="me"> 会渲染成 <a href="/me">

  • 如果是 /users/,那么又会渲染成 <a href="/users/me">

  • v6 中,无论当前 URL 是/user还是/users/, <Link to="me">都会渲染成<a href='/user/me'>

  • 也就是说 to 更像我们常用的 cd 命令行

<Route path="app">
  <Route path="dashboard">
    <Route path="stats" />
  </Route>
</Route>

//  当前 URL 为 /app/dashboard 或 /app/dashboard/
<Link to="stats">               => <a href="/app/dashboard/stats">
<Link to="../stats">            => <a href="/app/stats">
<Link to="../../stats">         => <a href="/stats">
<Link to="../../../stats">      => <a href="/stats">

// 命令行中, 当前目录为 /app/dashboard
cd stats                        # pwd is /app/dashboard/stats
cd ../stats                     # pwd is /app/stats
cd ../../stats                  # pwd is /stats
cd ../../../stats               # pwd is /stats

2.3.2 < Link replace >

replace:boolean ---->默认 false,即跳转路由要用 push 还是 replace


2.4 useNavigate

  • useHistory 被干掉了,换成了 useNavigate
import { useNavigate } from "react-router-dom";

function App() {
  const navigate = useNavigate();
  function handleClick() {
    navigate("/home");
  }
  return (
    <div>
      <button onClick={handleClick}>go home</button>
    </div>
  );
}
  • aviaget(to)默认就是 history.push 在当前路径上加上参数值
// v6
navigate('/home');
//v5
history.push('/home')
  • naviaget(to, { replace: true })就是 history.replace
// v6
navigate('/home', { replace: true });
//v5
history.replace('/home')
  • naviaget(to: number)就是 history.go
// v6
import { useNavigate } from "react-router-dom";

function App() {
  const navigate = useNavigate();

  return (
    <>
      <button onClick={() => navigate(-2)}>
        Go 2 pages back
      </button>
      <button onClick={() => navigate(-1)}>Go back</button>
      <button onClick={() => navigate(1)}>
        Go forward
      </button>
      <button onClick={() => navigate(2)}>
        Go 2 pages forward
      </button>
    </>
  );
}


//  v5
import { useHistory } from "react-router-dom";

function App() {
  const { go, goBack, goForward } = useHistory();

  return (
    <>
      <button onClick={() => go(-2)}>
        Go 2 pages back
      </button>
      <button onClick={goBack}>Go back</button>
      <button onClick={goForward}>Go forward</button>
      <button onClick={() => go(2)}>
        Go 2 pages forward
      </button>
    </>
  );
}
  • naviagete 与一样, 输入参数类似 cd 命令行
<Route path="app">
  <Route path="dashboard">
    <Route path="stats" />
  </Route>
</Route>

//  当前 URL 为 /app/dashboard 或 /app/dashboard/
<Link to="stats">               => <a href="/app/dashboard/stats">
<Link to="../stats">            => <a href="/app/stats">
<Link to="../../stats">         => <a href="/stats">
<Link to="../../../stats">      => <a href="/stats">

//  当前 URL 为 /app/dashboard 或 /app/dashboard/
const navigate = useNavigate()
navigate('stats') => '/app/dashboard/stats'
navigate('../stats') => '/app/stats'
navigate('../../stats') => '/stats'
navigate('../../../stats') => '/stats'

// 命令行中, 当前目录为 /app/dashboard
cd stats                        # pwd is /app/dashboard/stats
cd ../stats                     # pwd is /app/stats
cd ../../stats                  # pwd is /stats
cd ../../../stats               # pwd is /stats
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【React】react-router-dom 的相关文章

随机推荐

  • ubuntu17安装mysql后数据库乱码_ubuntu安装mysql数据库过程中出现依赖性Depends错误解决办法...

    1 sudo apt get update 2 sudo apt get install mysql server mysql client 若出现如下错误 无法安装 jianliu ubuntu sudo apt get install
  • PHP-Guzzle异步、并发

    参考 Guzzle文档 PHP Guzzle是一个HTTP客户端 可以使用它来发送各种HTTP请求 并发请求一 promises key1 gt client gt getAsync website1 key2 gt client gt g
  • el-table + setup语法糖 + 列表变化后滚动条置顶

    el table setup语法糖 列表变化后滚动条置顶 由于需要做一个el table 然后再更新地图同时将滚动条滚至最上 但是网上很多资料都是使用this refs 底部 this nextTick gt this refs table
  • SSM框架---springMVC

    目录 一 概述 分层思想 二 工作原理 1 导入jar包 2 创建启动类 三 处理请求参数 3 1 get方式 3 2 post方式 3 3 restful方式 推荐 四 处理get 请求的参数 五 处理post请求的参数 六 处理rest
  • ACM学习计划

    看完人家的博客 发现任重道远 一位高手对我的建议 一般要做到50行以内的程序不用调试 100行以内的二分钟内调试成功 acm主要是考算法的 主要时间是花在思考算法上 不是花在写程序与debug上 下面给个计划你练练 第一阶段 练经典常用算法
  • PHP的bcadd()函数用法

    求和后保留X位小数的函数 一般用于价格累加 查询出来的价格即使是浮点型 但是运用 后会变成整型 若需求需要保留小数位 则需要用到这个函数 bcadd 被加数 加数 保留几位小数 bcadd 1 3 2 4 00
  • 华为OD机试真题-最长密码【2023.Q1】

    题目描述 小王在进行游戏大闯关 有一个关卡需要输入一个密码才能通过 密码获得的条件如下 在一个密码本中 每一页都有一个由26个小写字母组成的若干位密码 每一页的密码不同 需要从这个密码本中寻找这样一个最长的密码 从它的末尾开始依次去掉一位得
  • 从零开始学前端(一)

    1 在桌面空白的地方 点击右键新建一个文本文档 2 双击或者右键打开刚刚新建的文件 3 将下面的代码复制到刚刚打开的txt文件中 h1 大家好 我是一只羊 这是我的第一个网页 h1 p Hello world p 4 点击文件 点击另存为
  • Mysql模糊查询like效率,以及更高效的写法

    原文来自 https www cnblogs com chaobest p 6737901 html 在使用msyql进行模糊查询的时候 很自然的会用到like语句 通常情况下 在数据量小的时候 不容易看出查询的效率 但在数据量达到百万级
  • Linux的学习步骤

    linux 基本操作命令 linux 各种配置 环境变量配置 网络配置 服务配置 linux 环境下搭建各种开发环境 Linux 写基本的shell脚本 对linux进行维护 Linux 安全设置 防止攻击 保障服务器的正常运行 能对系统尽
  • 飞腾CPU虚拟化相关代码分析(三)

    飞腾CPU虚拟化相关代码分析 三 函数set cpu boot mode flag 基本描述 根据CPU启动模式 来设置 boot cpu mode全局数组变量 函数输入输出描述 输入 寄存器w0 函数el2 setup的输出 寄存器w0
  • 树形dp(例题)

    树的最长路径带权值 树的直径可能时红色的边 从上图可以看出 每次要两个变量存放以u为根 最长路径d1 和次长路径d2 那么整个树的最长路径就有可能是d1 d2 我们每次要返回以u为根的贯穿试的最长路径 给他的父节点判断使用如下图 inclu
  • 如何求矩阵的逆矩阵

    如何求矩阵的逆矩阵 叮叮当当sunny 博客园 求逆矩阵最有效的方法是初等变换法 虽然还有别的方法 如果要求方阵 AA 的逆矩阵 标准的做法是 将矩阵 AA 与单位矩阵 II 排成一个新的矩阵 AI AI 将此新矩阵 AI AI 做初等行变
  • 埋点是什么?有什么作用?前端如何埋点?

    一 什么是埋点 埋点 tracking 是指在应用程序中插入代码或工具来记录某些事件的行为和属性 例如用户在应用中的点击 浏览 购买 注册等操作行为 这些数据可以被用来分析用户行为 优化产品功能 改进用户体验等 通过埋点 开发人员可以采集用
  • /Library/Developer/CommandLineTools/usr/bin/python3 :NO module named pytest解决

    报错场景 已经用pip3 install pytest 成功下载pytest 结果运行python3 m pytest xxx py还是报错 Library Developer CommandLineTools usr bin python
  • *python解决狼羊菜过河问题

    python解决狼羊菜过河问题 A岸有菜 羊 狼 农夫农夫必须将他们都送到B岸每次只能送一个 在保证他们不会被吃的前提下 完成任务 并得出步骤 代码 A 狼 1 羊 1 菜 1 B 狼 0 羊 0 菜 0 size len A count
  • 没有与这些操作数匹配的`“>>“`运算符错误;

    报错信息 没有与这些操作数匹配的 gt gt 运算符错误 网上查询大多是少了头文件
  • python反混淆javascript代码

    JavaScript代码一般都是可见的 一些关键的加密算法写在JS里其实很不安全 代码混淆能将Js进行压缩 使之变成不易读的代码 如下图所示 当然这难不倒我们 网上有很多js反混淆的工具 作者推荐使用jsbeautifier 因为最近项目用
  • CSDN上传付费资源需要创作者等级Lv4,我的升级之路,本文持续更新,欢迎各位分享自己的升级经验

    首先来看看官方的要求 创作者等级Lv4 实名认证 原力等级 5 目前惟一满足的实名认证 创作者等级升级官方说明 计分标准 计分规则 分值 说明 资源量 每上传1个资源 审核通过 5分 若自行或被平台删除及下架则扣除对应分数 分数实时更新 阅
  • 【React】react-router-dom

    文章目录 1 路由器组件 lt HashRouter gt lt BrowserRouter gt 2 路由 2 1 lt Route gt 2 1 1 lt Route element gt 2 1 2 lt Route path gt