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

在这里插入图片描述

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

本文目录

  • 1.params参数(useParams/useMatch)
  • 2.search参数(useSearchParams)
  • 3.state参数(useLocation)

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

坚持创作✏️,一起学习,码出未来‍!
【React Router v6】路由组件传参params/search/state(router v6)_第1张图片

1.params参数(useParams/useMatch)


【React Router v6】路由组件传参params/search/state(router v6)_第2张图片

如图所示,在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

示例重点在于: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>
  )
}

路由表文件/routes/index.js

{
  path: 'message',
  element: <Message />,
  children: [
    {
      path: 'detail/:id/:title/:content',
      element: <Detail />
    }
   ]
},

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 >
  )
}

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)

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

比如上面代码中打印的a:【React Router v6】路由组件传参params/search/state(router v6)_第3张图片

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

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

2.search参数(useSearchParams)

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

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

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

{
  path: 'message',
  element: <Message />,
  children: [
    {
     path: 'detail',
     element: <Detail />
    }
  ]
},

声明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 >
  )
}

useState()很像:

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

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

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

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

点击之后效果:【React Router v6】路由组件传参params/search/state(router v6)_第4张图片

同时路径变为/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>

从上面代码可以看出,传递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 >
  )
}

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

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

你可能感兴趣的:(React--从基础到实战,react.js,javascript,前端)