【React Router 6 快速上手二】useParams / useSearchParams / useLocation / 编程式路由导航useNavigate等API

前言

博主主页👉🏻蜡笔雏田学代码

专栏链接👉🏻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}
       
    
  )
})

在路由表中,声明接收params参数

routes=>index.jsx

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

这样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 (
    
  • ID:{id}
  • TITLE:{title}
  • CONTENT:{content}
) }

效果

在这里插入图片描述

2. 向路由组件传递search参数:useSearchParams()

作用:用于读取和修改当前位置的 URL 中的查询字符串。

返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。

向路由组件传递search参数:写法和v5一样

Message.jsx

message.map((m) => {
    return (
    // 路由链接
    <li key={m.id}>
        <Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>
        	{m.title}
        
    
  )
})

在路由表中,无需声明接收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:useLocation
  const x = useLocation()
  
  return (
    
  • ID:{id}
  • TITLE:{title}
  • CONTENT:{content}
) }

const [search, setSearch] = useSearchParams()

useSearchParams()拿到search参数,然后调身上的get()方法才能得到具体的某一个参数(id/title/content)

setSearch:主要用于更新收到的search参数的方法

  • <button onClick={() => setSearch('id=004&title=哈哈&content=嘻嘻')}> 点我更新一下search参数
  • 3. 向路由组件传递state参数:useLocation()

    向路由组件传递search参数:和v5不同(比v5更简单)

    Message.jsx

    message.map((m) => {
      return (
         // 路由链接
         <li key={m.id}>
           <Link
              to='detail'
              state={{
                id: m.id,
                title: m.title,
                content: m.content
              }}
           >{m.title}
         
       )
    })
    

    在路由表中,无需声明接收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 (
        
    • ID:{id}
    • TITLE:{title}
    • CONTENT:{content}
    ) }

    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}>
      <Link
    		to='detail'
    		state={{
           id: m.id,
           title: m.title,
           content: m.content
          }}
      >{m.title}
    	<button onClick={() => showDetail(m)}>查看详情
    
    

    点击查看详情按钮实现组件切换,需要使用一个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 (
        
          
            

    React Router Demo

    <button onClick={back}>⬅后退 <button onClick={forward}>➡前进 ) }

    在v5中,只有路由组件身上才有三个独有的属性:history/match/location,来实现各种跳转,一般组件想用路由组件身上的API,需要使用withRouter(),然而v6中,移除了withRouter(),想要实现编程式路由导航,使用useNavigate()这个Hook就能实现了,所以在Header一般组件引入useNavigate也能实现编程式路由导航。

    5. useInRouterContext()

    作用:如果组件在 的上下文中呈现(目前所处的组件被BrowserRouter包裹了),则 useInRouterContext 钩子返回 true,否则返回 false。

    6. useNavigationType()

    1. 作用:返回当前的导航类型(用户是如何来到当前页面的)。
    2. 返回值:POP、PUSH、REPLACE。
    3. 备注:POP是指在浏览器中直接打开了这个路由组件(刷新页面)。

    7. useOutlet()

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

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

    8. useResolvedPath()

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

    console.log(useResolvedPath('/user?id=001&name=tom#qwe'))
    //打印结果:
    //{pathname:'/user',search:'?id=001&name=tom',hash:'#qwe'}
    

    今天的分享就到这里啦✨

    \textcolor{red}{今天的分享就到这里啦✨}

    今天的分享就到这里啦✨

    原创不易,还希望各位大佬支持一下

    \textcolor{blue}{原创不易,还希望各位大佬支持一下}

    原创不易,还希望各位大佬支持一下

    🤞

    点赞,你的认可是我创作的动力!

    \textcolor{green}{点赞,你的认可是我创作的动力!}

    点赞,你的认可是我创作的动力!

    ⭐️

    收藏,你的青睐是我努力的方向!

    \textcolor{green}{收藏,你的青睐是我努力的方向!}

    收藏,你的青睐是我努力的方向!

    ✏️

    评论,你的意见是我进步的财富!

    \textcolor{green}{评论,你的意见是我进步的财富!}

    评论,你的意见是我进步的财富!

    本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/146b86f51a.html