• 【React Router v6】路由组件传参params/search/state(router v6)


    在这里插入图片描述

    欢迎来到我的博客
    📔博主是一名大学在读本科生,主要学习方向是前端。
    🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
    🛠目前正在学习的是🔥 R e a c t 框架 React框架 React框架🔥,中间穿插了一些基础知识的回顾
    🌈博客主页👉codeMak1r.小新的博客

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

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

    1.params参数(useParams/useMatch)

    在这里插入图片描述
    在这里插入图片描述

    如图所示,在Message组件下嵌套了一个子路由组件Detail。

    1. 点击导航栏消息1,路径变为localhost:3000/home/message/detail/001/消息1/锄禾日当午。
    2. 不点击时,路由组件Detail不显示;点击导航栏对应的消息1,则Detail组件显示内容为消息1对应内容。
    3. 路由组件Detail是一个通用组件,内部显示什么内容由点击的导航栏决定;点击哪一个导航,就将哪一个导航的内容通过params传递给Detail组件。
    4. 例如,点击消息2,将消息2的id、title与content传入Detail组件,以供Detail组件显示对应002这个id的内容。

    项目结构:

    src
    ├─App.jsx
    ├─index.js
    ├─routes
    |   └index.js
    ├─pages
    |   ├─About.jsx
    |   ├─Detail.jsx
    |   ├─Home.jsx
    |   ├─Message.jsx
    |   └News.jsx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    示例重点在于:Message组件本身是一个路由组件,其又是Detail组件的父组件,在Message组件中注册Detail子组件,点击导航栏对应链接,将对应的message消息内容传递给子路由组件Detail。然后Detail接收到父路由组件Message传递的params参数,将内容显示在页面对应位置中。

    Message组件

    import React, { useState } from 'react'
    import { Link, Outlet } from 'react-router-dom'
    
    export default function Message() {
      const [messages] = useState([
        { id: '001', title: '消息1', content: '锄禾日当午' },
        { id: '002', title: '消息2', content: '汗滴禾下土' },
        { id: '003', title: '消息3', content: '谁知盘中餐' },
        { id: '004', title: '消息4', content: '粒粒皆辛苦' },
      ])
      return (
        <div>
          <ul>
            {
              messages.map((msgObj) => {
                return (
                  // 路由链接
                  <li key={msgObj.id}>
                    <Link className="list-group-item"
                      to={`detail/${msgObj.id}/${msgObj.title}/${msgObj.content}`}
                    >{msgObj.title}</Link>
                  </li>
                )
              })
            }
          </ul>
          {/* 指定路由组件的展示位置 */}
          <Outlet />
        </div>
      )
    }
    
    • 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

    路由表文件/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

    Detail组件

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

    useParams()中接收params参数,然后渲染到页面中。

    其实还可以和react-router-dom v5一样,从match中拿到params参数:

    import {useMatch} from 'react-router-dom'
    const a = useMatch('/home/message/detail/:id/:title/:content')
    console.log(a)
    
    • 1
    • 2
    • 3

    使用useMatch()时,需要将当前组件Detail的URL路径传入hook作为参数,这样就可以接受到match了。

    比如上面代码中打印的a:在这里插入图片描述

    此时就可以直接解构拿到需要的params参数

    const {params: {id,title,content}} = useMatch('/home/message/detail/:id/:title/:content')
    
    • 1

    2.search参数(useSearchParams)

    上面我们学会了向路由组件传递params参数示例,我们还是运用这个示例,去体验一下向路由组件传递search参数。

    <Link className="list-group-item"
       to={`detail?id=${msgObj.id}&title=${msgObj.title}&content=${msgObj.content}}`}
    >{msgObj.title}</Link>
    
    • 1
    • 2
    • 3

    还是与v5版本的react-router-dom一样,路由组件传递search参数不需要声明接收,也就是路由表文件/routes/index.js

    {
      path: 'message',
      element: <Message />,
      children: [
        {
         path: 'detail',
         element: <Detail />
        }
      ]
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    声明Detail组件时不需要声明接收参数。

    Deatil组件

    import React from 'react'
    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 (
        <ul>
          <li>消息编号:{id}</li>
          <li>标题:{title}</li>
          <li>内容:{content}</li>
        </ul >
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    useState()很像:

    useSearchParams()函数返回一个数组,数组第一项是search数据,数组第二项是修改search数据的方法。

    并且接受到search还不能直接使用数据,需要调用search上的get方法,传入需要使用的数据项的名字,才能真正接受到数据,笔者个人觉得这是最麻烦的路由组件传递参数的方法…

    可以在页面中添加一个button按钮,点击按钮修改search参数

     <button onClick={() => setSearch('id=008&title=哈哈&content=嘻嘻')}>
     		点我更新收到的search参数
     </button>
    
    • 1
    • 2
    • 3

    点击之后效果:在这里插入图片描述

    同时路径变为/home/message/detail?id=007&title=哈哈&content=嘻嘻

    3.state参数(useLocation)

    上面学会了向路由组件传递params以及search参数,接下来还是运用这个案例去讲解向路由组件传递state参数。

    <Link className="list-group-item"
       to='detail'
       state={{
         id: msgObj.id,
         title: msgObj.title,
         content: msgObj.content
       }}
    >{msgObj.title}</Link>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    从上面代码可以看出,传递state参数时,to属性的值还是正常的一个"deatil",只需要为Link添加一个state属性(值为对象)即可。

    state参数与search参数一样,不需要在路由表中声明接收。

    需要注意的是,⚠️state参数不显示在url地址栏中,而之前学习的params参数以及search参数都会在url地址栏中显示。

    Detail组件

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

    useLocation()函数相当于类组件中的this.props.location.

    在调用函数时不需要传递参数,从返回值中直接解构出需要的state参数即可。

  • 相关阅读:
    Linux基本命令总结练习(过命令关)
    [需求管理-6]:需求分析 - 技术可行性研究与方案设计模板
    java 写excel文件
    computer planetary MoBI:生物多样性重要性地图
    Django项目实现对外POST接口
    Llama2-Chinese项目:7-外延能力LangChain集成
    底层驱动day2作业
    【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day08
    使用 JS 实现在浏览器控制台打印图片 console.image()
    使用pytorch实现一个线性回归训练函数
  • 原文地址:https://blog.csdn.net/Svik_zy/article/details/126203649