• 09-React路由使用(React Router 6)


    9-React Router 6的使用


    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.常用路由API

    1).一级路由导航

    a.路由导航基本实现

    在React Router 5版本中,使用 来实现基本的路由导航实现,使用提升路由的查找效率。在React Router 6版本中 等标签进行了保留,移除了,让新标签```代替

    // 一级路由的基本实现
    import { NavLink, Route, Routes,Navigate } from 'react-router-dom'
    export default function App() {
      return (
        
    About Home
    } /> } />
    ) }
    • 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
    1. 说明: 用于包裹整个应用。

    2. 示例代码:

      import React from "react";
      import {createRoot} from 'react-dom/client';
      import {BrowserRouter} from 'react-router-dom'
      import App from "./App";
      createRoot(document.getElementById('root')).render(
          
              {/* 整体结构(通常为App组件) */}
              
          
      )
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    1. 说明:作用与一样,但修改的是地址栏的hash值。
    2. 备注:6.x版本中 的用法与 5.x 相同。
    1. v6版本中移出了先前的,引入了新的替代者:

    2. 要配合使用,且必须要用包裹

    3. 相当于一个 if 语句,如果其路径与当前 URL 匹配,则呈现其对应的组件。

    4. 属性用于指定:匹配时是否区分大小写(默认为 false)。

    5. 当URL发生变化时, 都会查看其所有子 元素以找到最佳匹配并呈现组件 。

    6. 也可以嵌套使用,且可配合useRoutes()配置 “路由表” ,但需要通过 组件来渲染其子路由。

    7. 示例代码:

      
          /*path属性用于定义路径,element属性用于定义当前路径所对应的组件*/
          }>
      
          /*用于定义嵌套路由,home是一级路由,对应的路径/home*/
          }>
              /*test1 和 test2 是二级路由,对应的路径是/home/test1 或 /home/test2*/
              }>
              }>
          
      
          //Route也可以不写element属性, 这时就是用于展示嵌套的路由 .所对应的路径是/users/xxx
          
              } />
          
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    1. 作用: 修改URL,且不发送网络请求(路由链接)。
    2. 注意: 外侧需要用包裹。
    b.路由导航的重定向

    在React Router 5版本中,使用进行重定向,在在React Router 6版本中使用实现重定向

    export default function App() {
      return (
        
    About Home
    } /> } /> }/>
    ) }
    • 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
    1. 作用:只要组件被渲染,就会修改路径,切换视图。

    2. replace属性用于控制跳转模式(push 或 replace,默认是push)。

    3. 示例代码:

      import React,{useState} from 'react'
      import {Navigate} from 'react-router-dom'
      
      export default function Home() {
      	const [sum,setSum] = useState(1)
      	return (
      		

      我是Home的内容

      {/* 根据sum的值决定是否切换视图 */} {sum === 1 ?

      sum的值为{sum}

      : }
      ) }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    c.路由的高亮效果

    在React Router 5版本中,使用 进行路由导航高亮,在React Router 6版本中还有一种通过判断条件的方法

    //写法一
     isActive?"list-group-item atguigu":"list-group-item"} to="/about">About
     isActive?"list-group-item atguigu":"list-group-item"} to="/home">Home
    
    • 1
    • 2
    • 3
    //写法二
    function computedClassName({isActive}) {
        return isActive?"list-group-item atguigu":"list-group-item"
    }
    About
    Home
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    分析:

    1. 写在className中的箭头函数会接收到一个对象

       {console.log(a);}} to="/about">About
      Home
      
      • 1
      • 2

    2. 这个对象中有一个isActive属性,它会存储该组件是否处于显示状态,是就返回true

    3. 可以将这个属性解构出来,通过读取判断这个属性的布尔值动态为元素添加高亮的样式

       isActive?"list-group-item atguigu":"list-group-item"} to="/about">About
       isActive?"list-group-item atguigu":"list-group-item"} to="/home">Home
      
      • 1
      • 2

    1. 作用: 与组件类似,且可实现导航的“高亮”效果。

    2. 示例代码:

      // 注意: NavLink默认类名是active,下面是指定自定义的class
      
      //自定义样式
       {
              console.log('home', isActive)
              return isActive ? 'base one' : 'base'
          }}>login
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      /*
      	默认情况下,当Home的子组件匹配成功,Home的导航也会高亮,
      	当NavLink上添加了end属性后,若Home的子组件匹配成功,则Home的导航没有高亮效果。
      */
      home
      
      • 1
      • 2
      • 3
      • 4
      • 5

    d.路由表

    也可以嵌套使用,且可配合useRoutes()配置 “路由表” ,但需要通过 组件来渲染其子路由。

    export default function App() {
        // 根据路由表生成对应的路由规则
        const element=useRoutes([
            {
                path: '/about',
                element: 
            },
            {
                path: '/home',
                element: 
            },
            {
                path: '/',
                element: 
            },
        ])
        return (
            
    About Home
    {element}
    ) }
    • 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
    • 39
    • 40
    • 41
    useRoutes()
    1. 作用:根据路由表,动态创建

    2. 示例:

      1. 一般会将路由表写到另一个文件中进行管理,便于多个组件引入使用

        //路由表配置:src/routes/index.js
        import About from '../pages/About'
        import Home from '../pages/Home'
        import {Navigate} from 'react-router-dom'
        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
      2. 进路由表的规则引入到组件中使用

        //App.jsx
        import React from 'react'
        import {NavLink,useRoutes} from 'react-router-dom'
        import routes from './routes'
        export default function App() {
        	//根据路由表生成对应的路由规则
        	const element = useRoutes(routes)
        	return (
        		
        ...... {/* 注册路由 */} {element} ......
        ) }
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16

    2).多级路由导航

    a.多级路由基本实现
    1. 在路由表中编写多级路由规则

      //路由表配置:src/routes/index.js
      export default [
          {
              path: '/about',
              element: <About />
          },
          {
              path: '/home',
              element: <Home />,
              children: [
                  {
                      path: 'news',
                      element: <News />
                  },
                  {
                      path: 'message',
                      element: <Message />,
                      children: [
                          {
                              path: 'detail',
                              element: <Detail />
                          }
                      ]
                  }
              ]
          },
          {
              path: '/',
              element: <Navigate to="/about" />
          },
      ]
      
      • 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
    2. 使用渲染一级路由的后续子路由

      产生嵌套时,渲染其对应的后续子路由。

      export default function Home() {
        return (
          

      我是Home组件

      {/* 指定路由组件呈现的位置 */}
      ) }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    b.多级路由传递参数
    ①.传递params参数
    1. 在路由表中的路由规则中编写参数名进行占位

      //路由表配置:src/routes/index.js
      {
          path: 'message',
          element: <Message />,
          children: [
              {
                  path: 'detail/:id/:title/:content',
                  element: <Detail />
              }
          ]
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    2. 在组件的路由链接的匹配路径中编写传入的参数

      export default function Message() {
        const [messages] = useState([
          { id: '1', title: '消息1', content: '锄禾日当午' },
          { id: '2', title: '消息2', content: '汗滴禾下土' },
          { id: '3', title: '消息3', content: '谁时盘中餐' },
          { id: '4', title: '消息4', content: '粒粒皆辛苦' },
        ])
        return (
          
        { messages.map(message => { return (
      • {/* {message.title}   */} {message.title}  
      • ) }) }
      ) }
      • 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
    3. 在路由组件中使用useParams这个HOOKS读取parpms参数

      useParams

      作用:回当前匹配路由的params参数,类似于5.x中的match.params

      import {useParams,useMatch} from 'react-router-dom'
      export default function Detail() {
        const {id,title,content}=useParams()
        return (
          
      • 消息编号:{id}
      • 消息标题:{title}
      • 消息内容:{content}
      ) }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      分析:

      useParams这个函数会将路由路径中的params参数包装成一个对象返回

      const a=useParams();
      console.log(a);
      
      • 1
      • 2

      useMatch()
      1. 作用:返回当前匹配信息,对标5.x中的路由组件的match属性。

      2. 示例代码:

        }/>
        登录
        
        export default function Login() {
          const match = useMatch('/login/:x/:y')
          console.log(match) //输出match对象
          //match对象内容如下:
          /*
          	{
              params: {x: '1', y: '10'}
              pathname: "/LoGin/1/10"  
              pathnameBase: "/LoGin/1/10"
              pattern: {
              	path: '/login/:x/:y', 
              	caseSensitive: false, 
              	end: false
              }
            }
          */
          return (
          	

        Login

        ) }
        • 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
    ②.传递search参数
    1. 传递search参数不需要在·路由表文件中匹配参数占位符

    2. 父组件将参数编写到路由路径中

      {message.title}
      
      • 1
    3. 子组件使用useSearchParams函数读取传入的search参数

      useSearchParams

      1. 作用:用于读取和修改当前位置的 URL 中的查询字符串。
      2. 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。
      import {useSearchParams} from 'react-router-dom'
      export default function Detail() {
        const [search,setSearch]=useSearchParams()
        const id=search.get('id')
        const title=search.get('title')
        const content=search.get('content')
        return (
          
      • 消息编号:{id}
      • 消息标题:{title}
      • 消息内容:{content}
      ) }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    4. 分析:

      1. 需要创建一个数组来接受useSearchParams函数的返回值;数组中第一个元素为search,不能直接使用search中的数值,需要用其中自带的get方法获取指定key的数值;另一个为修改search的方法名

        const [search,setSearch]=useSearchParams()
          const id=search.get('id')
          const title=search.get('title')
          const content=search.get('content')
        
        • 1
        • 2
        • 3
        • 4
      2. setSearch方法可以直接修改search中的数值

        
        
        • 1

    ③.传递state参数
    1. 传递search参数不需要在·路由表文件中匹配参数占位符

    2. 父组件将参数编写到路由路径中

      {id:message.id,title:message.title,content:message.content}}>{message.title}
      
      • 1
    3. 子组件使用useSearchParams函数读取传入的state参数

      import {useLocation} from 'react-router-dom'
      export default function Detail() {
       	//   多重解构
          const {state:{id,title,content}}=useLocation()
          return (
              
      • 消息编号:{id}
      • 消息标题:{title}
      • 消息内容:{content}
      ) }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      分析:

      1. useSearchParams函数会返回一个对象,这个对象中就包含了存储了state参数的属性

        const a=useLocation()
        console.log(a);
        
        • 1
        • 2

    3).编程式路由导航

    useNavigate()
    1. 作用:返回一个函数用来实现编程式导航。

    2. 使用:

      1. 第一种使用方式:指定具体的路径

        export default function Message() {
          const navigate = useNavigate()
          function showDetail(message) {
            navigate('/about')
          }
          return (
            
          { messages.map(message => { return (
        • {message.title}
        • ) }) }
        ) }
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23

        如果需要传递数值,params参数和search参数直接写在路径中,state参数则配置成一个对象

        export default function Message() {
          const navigate = useNavigate()
          const [messages] = useState([
            { id: '1', title: '消息1', content: '锄禾日当午' },
            { id: '2', title: '消息2', content: '汗滴禾下土' },
            { id: '3', title: '消息3', content: '谁时盘中餐' },
            { id: '4', title: '消息4', content: '粒粒皆辛苦' },
          ])
          function showDetail(message) {
            navigate('detail',{
              replace:false,
              state:{
                id:message.id,
                title:message.title,
                content:message.content
              }
            })
          }
          return (
            
          { messages.map(message => { return (
        • {message.title}  
        • ) }) }
        ) }
        • 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

      2. 第二种使用方式:传入数值进行前进或后退,类似于5.x中的 history.go()方法

        import { useNavigate} from 'react-router-dom'
        export default function Header() {
          const navigate = useNavigate()
          function go() {
            navigate(1)
          }
          function back() {
            navigate(-1)
          }
          return (
            

        React Router Demo

        ) }
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19


    3.非常用路由API

    1).useInRouterContext()

    作用:如果组件在 的上下文中呈现,则 useInRouterContext 钩子返回 true,否则返回 false。

    import { useNavigate,useInRouterContext} from 'react-router-dom'
    export default function Header() {
      const navigate = useNavigate()
      console.log('Header',useInRouterContext());
      return (
        

    React Router Demo

    ) }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2). useNavigationType()

    1. 作用:返回当前的导航类型(用户是如何来到当前页面的)。

    2. 返回值:POPPUSHREPLACE

      //PUSH方式
      News
      
      • 1
      • 2
      //REPLACE方式
      News
      
      • 1
      • 2
    3. 备注:POP是指在浏览器中直接打开了这个路由组件(刷新页面)。

    3). useOutlet()

    1. 作用:用来呈现当前组件中渲染的嵌套路由。

    2. 示例代码:

      const result = useOutlet()
      console.log(result)
      // 如果嵌套路由没有挂载,则result为null
      // 如果嵌套路由已经挂载,则展示嵌套的路由对象
      
      • 1
      • 2
      • 3
      • 4

    4).useResolvedPath()

    1. 作用:给定一个 URL值,解析其中的:path、search、hash值。

      console.log(useResolvedPath('/user?id=001&name=tom#qwe'));
      
      • 1

  • 相关阅读:
    什么是数据应用程序
    Java-JDBC快速上手
    我的编程之路
    React - 实现瀑布流加载
    【kali-漏洞利用】(3.2)Metasploit基础(下):MSF终端利用过程
    《深入理解Java虚拟机》——Java内存区域与内存溢出异常
    Softmax 回归 + 损失函数 + 图片分类数据集
    SpringBoot ORM操作MySQL、REST接口架构风格、集成Redis和集成Dubbo
    python使用grpc
    【wxWidgets实现透明wxPanel_核心实现_原创思想】
  • 原文地址:https://blog.csdn.net/m0_57262196/article/details/133975834