前言
博主主页蜡笔雏田学代码
专栏链接React专栏
之前学习了react-router-dom5版本的相关内容
参考文章React路由组件传参的三种方式和 【React路由】编程式路由导航
回顾上篇文章【React Router 6 快速上手一】,今天来学习react-router-dom6版本的另一些相关知识!
感兴趣的小伙伴一起来看看吧~
文章目录
- 1. 向路由组件传递params参数:useParams()
- 2. 向路由组件传递search参数:useSearchParams()
- 3. 向路由组件传递state参数:useLocation()
- 4. 编程式路由导航useNavigate()
- 5. useInRouterContext()
- 6. useNavigationType()
- 7. useOutlet()
- 8. useResolvedPath()
1. 向路由组件传递params参数:useParams()
在v5版本中,路由组件传递参数方式有三种:params、search、state。在v6中,都能用这三种方式,但是写法不一样了。
当点击消息1这个导航链接时,展示下方对应的Detail路由组件,并向这个组件传递params参数(ID,TITLE,CONTENT)信息。
向路由组件传递params参数:
和v5一样,在路径后面跟上想要传递的值
Message.jsx
message.map((m) => {return (// 路由链接<li key={m.id}> <Link to={`detail/${m.id}/${m.title}/${m.content}`}> {m.title} </Link> </li>)})
在路由表中,声明接收params参数:
routes=>index.jsx
{path: 'message',element: <Message />,children: [ { path: 'detail/:id/:title/:content', element: <Detail /> } ]}
这样id,title参数就传递给了Detail组件,Detail组件就要拿到这三个参数,在v5版本中是通过
this.props.match.params
拿到参数,但是v6中,函数式组件没有this,所以不能用这种方式,需要借助一个Hook:useParams
。
Detail.jsx
import React from 'react'import { useParams } from 'react-router-dom';export default function Detail() {// 获取URL中携带过来的params参数const { id, title, content } = useParams()// console.log(a)//{id: '001', title: '消息1', content: '你好'}//还可以使用另外一个Hook:useMatch(比较麻烦)//const x = useMatch('/home/message/detail/:id/:title/:content')return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{content}</li></ul>)}
效果
2. 向路由组件传递search参数:useSearchParams()
作用:用于读取和修改当前位置的 URL 中的查询字符串。
返回一个包含两个值的数组,内容分别为:
当前的seaech参数
、更新search的函数
。
向路由组件传递search参数:
写法和v5一样
Message.jsx
message.map((m) => {return (// 路由链接<li key={m.id}><Link to={`detail" />${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link> </li>)})
在路由表中,无需声明接收params参数。
Detail组件要拿到传递过来的参数,需要使用一个Hook:useSearchParams
(和useState方法类似)。
Detail.jsx
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')//还可以使用另外一个Hook:useLocationconst x = useLocation()return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{content}</li></ul>)}
const [search, setSearch] = useSearchParams()
useSearchParams()拿到search参数,然后调身上的get()方法才能得到具体的某一个参数(id/title/content)
setSearch:主要用于
更新收到的search参数的方法
<li><button onClick={() => setSearch('id=004&title=哈哈&content=嘻嘻')}>点我更新一下search参数</button></li>
3. 向路由组件传递state参数:useLocation()
向路由组件传递search参数:
和v5不同(比v5更简单)
Message.jsx
message.map((m) => {return ( // 路由链接 <li key={m.id}> <Linkto='detail'state={{id: m.id,title: m.title,content: m.content}} >{m.title}</Link> </li> )})
在路由表中,无需声明接收params参数。
Detail组件要拿到传递过来的参数,需要使用一个Hook:useLocation
import React from 'react'import { useLocation } from 'react-router-dom'export default function Detail() {//连续解构赋值const { state: { id, title, content } } = useLocation()return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{content}</li></ul>)}
4. 编程式路由导航useNavigate()
需求
现在我想在每一个消息的后面有一个”点我查看详情”按钮,下方展示详情内容,之前都是靠Link来展示详情内容。
效果
Message.jsx
import {useNavigate } from 'react-router-dom'...const navigate = useNavigate()function showDetail(m) {navigate('detail', //路径 //配置对象 {replace: false, //push模式//只能写state,不能写search/params参数//如果是search/params参数,直接写在路径里state: {id: m.id,title: m.title,content: m.content}})}...// 路由链接<li key={m.id}><Linkto='detail'state={{ id: m.id, title: m.title, content: m.content}}>{m.title}</Link> <button onClick={() => showDetail(m)}>查看详情</button></li>
点击查看详情按钮实现组件切换,需要使用一个Hook:useNavigate,原来v5版本通过this.props.history可以完成的功能(前进/后退),navigate()都可以完成,navigate不像this.props.history有很多API(goBack/goForward)。
那么,如果想用useNavigate实现后退或前进功能呢?
新增一个非路由Header组件:
components/Header.jsx
import React from 'react'import { useNavigate } from 'react-router-dom'export default function Header() {const navigate = useNavigate()function back() {navigate(-1)}function forward() {navigate(1)}return (<div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2><button onClick={back}>⬅后退</button><button onClick={forward}>➡前进</button></div></div>)}
在v5中,只有路由组件身上才有三个独有的属性:history/match/location,来实现各种跳转,一般组件想用路由组件身上的API,需要使用withRouter(),然而v6中,
移除了withRouter()
,想要实现编程式路由导航,使用useNavigate()这个Hook就能实现了,所以在Header一般组件引入useNavigate也能实现编程式路由导航
。
5. useInRouterContext()
作用:如果组件在
的上下文中呈现(目前所处的组件被BrowserRouter包裹了),则
useInRouterContext
钩子返回 true,否则返回 false。
6. useNavigationType()
- 作用:返回当前的导航类型(用户是如何来到当前页面的)。
- 返回值:
POP
、PUSH
、REPLACE
。 - 备注:
POP
是指在浏览器中直接打开了这个路由组件(刷新页面)。
7. useOutlet()
作用:用来呈现当前组件中渲染的嵌套路由组件。
const result = useOutlet()console.log(result)// 如果嵌套路由没有挂载,则result为null// 如果嵌套路由已经挂载,则展示嵌套的路由对象
8. useResolvedPath()
作用:解析路径,给定一个 URL值,解析其中的:path、search、hash值。
console.log(useResolvedPath('/user" />))//打印结果://{pathname:'/user',search:'?id=001&name=tom',hash:'#qwe'}
今天的分享就到这里啦✨\textcolor{red}{今天的分享就到这里啦✨} 今天的分享就到这里啦✨
原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下
点赞,你的认可是我创作的动力!\textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!\textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!\textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!