• 【React Router v6】快速上手react-router-dom6(对比 router5)


    在这里插入图片描述

    本文被专栏【React–从基础到实战】收录

    🕹坚持创作✏️,一起学习📖,码出未来👨🏻‍💻!
    在这里插入图片描述

    React Router 6 快速上手

    在之前的文章中,我们已经学习了react-router-dom v5的内容,在react-router-dom v6版本中,对旧版本的API以及一些组件做了些许修改。本文开始,我将带大家学习最新的react-router-dom v6版本的路由知识,并且会与v5老版本进行一些对比。

    需要学习react-router-dom v5版本的可以点击:

    react-router-dom入门

    react-router-dom入门2

    1.概述

    1. React Router 以三个不同的包发布到npm上,它们分别为:
      1. react-router:路由的核心库,提供了很多的:组件、钩子
      2. react-router-dom:包含react-router所有内容,并添加了一些专门用于DOM的组件,例如
      3. react-router-native:包括react-router所有内容,并添加一些专门用于ReactNative的API,例如
    2. 与React Router 5.x版本相比,改变了什么?
      1. 内置组件的变化:移除,新增
      2. 语法的变化:component={About}变为element={}
      3. 新增多个hook:useParamsuseNavigateuseMatch
      4. 官方明确推荐函数式组件!

    2.基本使用

    我们还是使用之前讲解react-router-dom@5的示例。

    在这里插入图片描述

    import React, { Fragment } from 'react'
    import { NavLink, Routes, Route } from 'react-router-dom'
    import About from './pages/About'
    import Home from './pages/Home'
    
    export default function App() {
      return (
        <Fragment>
          <div>
            <div className="row">
              <div className="col-xs-offset-2 col-xs-8">
                <div className="page-header"><h2>React Router Demo</h2></div>
              </div>
            </div>
            <div className="row">
              <div className="col-xs-2 col-xs-offset-2">
                <div className="list-group">
        					 // 编写路由链接
                  <NavLink className='list-group-item' to="/home">Home</NavLink >
                  <NavLink className='list-group-item' to="/about">About</NavLink >
                </div>
              </div>
              <div className="col-xs-6">
                <div className="panel">
                  <div className="panel-body">
                    {/* 注册路由 */}
                    <Routes>
                      <Route path='/about' element={<About />} />
                      <Route path='/home' element={<Home />} />
                    </Routes>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </Fragment>
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    注意⚠️,在v6版本中,依旧需要将外层App组件用 < B r o w s e r R o u t e r > <BrowserRouter>标签包裹起来。

    const root = ReactDOM.createRoot(document.getElementById('root'))
    root.render(
    <React.StrictMode>
     <BrowserRouter>
       <App />
     </BrowserRouter>
    </React.StrictMode>,
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.重定向

    在react-router-dom v5版本中,我们是使用Redirect进行重定向的,但是在新版本中呢,删除了Redirect,换成了另一个叫做:Navigate

    // 重定向
    // react-router-dom v5
    <Redirect to="/home" />
      
    // react-router-dom v6
    <Route path='/' element={<Navigate to="/home" />} />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    值得注意的是,Navigate组件接收两个属性,一个是上面提到的to属性,另一个属性是replace

    <Navigate to="/about" replace />
    
    • 1

    我们知道,路由的跳转有两种模式,一种是pushpush会将这个url压入路由history栈顶; replace模式会将栈顶的url替换

    Navigate组件中可以设置replace的值为true或者false,默认为false,也就是重定向默认是push模式跳转。

    4.NavLink高亮

    高亮样式

    .LinkBackColor {
      background-color: orange !important;
      color: white !important;
    }
    
    • 1
    • 2
    • 3
    • 4

    修改高亮之前在这里插入图片描述

    修改高亮之后在这里插入图片描述
    react-router-dom v5中,实现NavLink高亮使用的是NavLink组件标签中的activeClassName属性。

    <NavLink activeClassName='LinkBackColor' className="list-group-item" to="/about">About</NavLink>
    
    • 1

    但是在新版本v6中,我们如果想实现NavLink高亮效果,需要将className属性设置为一个函数。

    <NavLink className={
       ({ isActive }) => { return isActive ? "list-group-item LinkBackColor" : "list-group-item" }
    } to="/about">About</NavLink >
    
    • 1
    • 2
    • 3

    代码优化

    将计算className的值封装成一个函数

    function computedClassName({ isActive }) {
      return isActive ? "list-group-item LinkBackColor" : "list-group-item"
    }
    
    <NavLink className={computedClassName} to="/home">Home</NavLink >
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5.useRoutes路由表

    在Vue中,Vue CLI脚手架搭建完毕之后,项目目录中就会有一个router文件夹,里面就是用来存放路由表的。

    在react-router-dom v6版本中,也可以很轻松的把路由都中心化地维护在路由表中了。

    src结构
    ├─App.jsx
    ├─index.js
    ├─routes
    |   └index.js
    ├─pages
    |   ├─About.jsx
    |   └Home.jsx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    /routes/index.js

    import { Navigate } from "react-router-dom"
    import About from "../pages/About"
    import Home from "../pages/Home"
    
    export default [
      {
        path: '/about',
        element: <About />
      },
      {
        path: '/home',
        element: <Home />
      },
      {
        path: '/',
        element: <Navigate to="/about" />
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    使用路由表

    import { NavLink, useRoutes } from 'react-router-dom'
    import routes from './routes'
    
    // 根据路由表生成对应的路由规则
    const element = useRoutes(routes)
    
    // 注册路由
    + {element}
    - <Routes>
    -  <Route path='/about' element={<About />} />
    -  <Route path='/home' element={<Home />} />
    -  <Route path='/' element={<Navigate to="/about" />} />
    - </Routes>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6.嵌套路由(Outlet)

    在这里插入图片描述

    如图所示,Message与News都是Home组件下的子路由组件,这里的/home/message与/home/news就发生了路由的嵌套。

    我们还是使用路由表来统一维护路由组件。

    首先修改路由表:

    {
      path: '/home',
      element: <Home />,
      children: [
        {
          path: 'message',
          element: <Message />
        },
        {
          path: 'news',
          element: <News />
        }
      ]
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    将嵌套的二级路由放在children属性中注册,这一点与Vue类似。

    Home组件:

    import React from 'react'
    import { NavLink, Outlet } from 'react-router-dom'
    
    export default function Home() {
      return (
        <div>
          <h2>Home组件内容</h2>
          <div>
            <ul className="nav nav-tabs">
              <li>
                <NavLink className='list-group-item' to='news'>News</NavLink>
              </li>
              <li>
                <NavLink className='list-group-item' to='message'>Message</NavLink>
              </li>
            </ul>
            {/* 指定路由组件呈现的位置 */}
            <Outlet />
          </div>
        </div>
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    News
    中的to属性有三种写法:
    1. to='news'
    2. to='./news'
    3. to='/home/news'  //这一种与react-router-dom5中一样
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Outlet组件用于指定嵌套路由组件呈现的位置,详细的说明会在后续专栏文章《总结路由API》中提到。

  • 相关阅读:
    基于SpringBoot的校园周边美食探索及分享平台的设计与实现
    Vue学习——目录结构与运行流程(20)
    linux 给根目录扩容(lvm CentOS 7.6 &kylinx86)
    GBASE 8A v953报错集锦48--远程 rmt 导出 dual 表数据没有落到本地而是落到了集群节点上
    RabbitMQ的工作模式
    Redis实战 - 02 Redis 保存短信验证码实现用户注册
    【Network】网络编程套接字 —— socket编程
    VTP协议
    Source map 超详细学习攻略_番茄出品
    Android 蓝牙开发( 四 )
  • 原文地址:https://blog.csdn.net/Svik_zy/article/details/126203283