欢迎来到我的博客
博主是一名大学在读本科生,主要学习方向是前端。
目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
目前正在学习的是 R e a c t 框架 React框架 React框架,中间穿插了一些基础知识的回顾
博客主页codeMak1r.小新的博客本文目录
- 1.params参数(useParams/useMatch)
- 2.search参数(useSearchParams)
- 3.state参数(useLocation)
本文被专栏【React–从基础到实战】收录
如图所示,在Message组件下嵌套了一个子路由组件Detail。
项目结构:
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了。
此时就可以直接解构拿到需要的params参数
const {params: {id,title,content}} = useMatch('/home/message/detail/:id/:title/:content')
上面我们学会了向路由组件传递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>
同时路径变为/home/message/detail?id=007&title=哈哈&content=嘻嘻
上面学会了向路由组件传递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参数即可。