我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文讲述React路由提供的useMatch()钩子,它和useParams()钩子很类似,都可以用来获得隐藏在路径中的参数信息。那么,两者有什么区别和联系呢?这就是本文要考虑的问题。

苏南大叔:React路由,useMatch获取参数,和useParams有何区别? - react-usematch
React路由,useMatch获取参数,和useParams有何区别?(图3-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0create-react-app@5.0.1react-router-dom@6.27.0react@18.3.1

前文回顾

在组件里面获得路由传递的参数信息,一般有两种方式。

  • 第一种是把参数隐藏到路径里,在组件中使用useParams()进行解析。【推荐】
  • 第二种是把参数明文写在url?后面,使用&符合进行串联。在组件里面使用useSearchParams()进行解析。

具体的使用方式,可以参考文章:

useParams()

在苏南大叔前面的文章里面,可以得知:路由的定义方式,大体上可以分为两种。

  • 一种是通过<Route>path属性进行定义。
  • 另外一种是通过数组的path属性进行定义,然后通过createXxxRouter()函数最终生效。

无论是那种定义方法,都是通过修改path属性,来定义参数的。例如:路由定义path/post/:id/:title,就会在对应的element里面,使用下面的方式获得真实的参数:

import { useParams } from "react-router-dom";
export default ()=>{
  var { id, title } = useParams();
  //...
}

也就是说:

  • 参数的名字,是在路由的path里面定义的。
  • 参数值的获取,是在组件里面使用useParams()获得的。

useMatch()

useMatch()的官方文档是:

几乎啥也没写,一如既往的让人迷糊

使用的最简单方式如下:

import { useMatch } from "react-router-dom";
export default ()=>{
  const { params: { page2, id2, title2 } } = useMatch("/:page2/:id2/:title2");
  // console.log(page2, id2, title2);
  //...
}

使用方式二:

import { useMatch } from "react-router-dom";
export default ()=>{
  const match = useMatch("/:page3/:id3/:title3");
  console.log( match );
  console.log( match.params.id3, match.params.title3, match.params.page3 );
  //...
}

对比测试代码

苏南大叔:React路由,useMatch获取参数,和useParams有何区别? - 匹配结果对比
React路由,useMatch获取参数,和useParams有何区别?(图3-2)

完整测试代码:

import { useParams } from "react-router-dom";
import { useMatch } from "react-router-dom";
export default () => {
  var { id, title } = useParams();
  const {
    params: { page2, id2, title2 },
  } = useMatch("/:page2/:id2/:title2");
  const match = useMatch("/:page3/:id3/:title3");
  console.log(match);
  return (
    <>
      <table>
        <tr>
          <td>useParams</td>
          <td>{id}</td>
          <td>{title}</td>
          <td></td>
        </tr>
        <tr>
          <td>useMatch</td>
          <td>{id2}</td>
          <td>{title2}</td>
          <td>{page2}</td>
        </tr>
        <tr>
          <td>useMatch</td>
          <td>{match.params.id3}</td>
          <td>{match.params.title3}</td>
          <td>{match.params.page3}</td>
        </tr>
      </table>
    </>
  );
};

路由部分,任选方案。只记得设置path/post/:id/:title即可,它会作用于useParams()的结果。

match对象匹配写法

关于useMatch的第一个写法,{params:{}},这种写法很罕见。但是,如果结合第二种写法的返回值match.params来看的话,第一种写法中的params关键字就比较好理解了,它指代的就是match.params

match的打印输出是:

{
  params: {page3: 'post', id3: '123', title3: 'demo'}
  pathname: "/post/123/demo"
  pathnameBase: "/post/123/demo"
  pattern: {caseSensitive:false,end:true,path:"/:page3/:id3/:title3"}
}

独立新的匹配动作

useMatch()可以理解为一次取参数行为的优化。使用useMatch()的时候,

  • 当前的location是个隐藏的参数,隐式调用useLocation()
  • 然后,可以自己定义路径的匹配规则(参数名字),类似于上边的路由定义里面的:id。两者不冲突,没关系。

苏南大叔:React路由,useMatch获取参数,和useParams有何区别? - 虚实参数传递
React路由,useMatch获取参数,和useParams有何区别?(图3-3)

或者说,钩子useMatch()也能取得隐藏在location.pathname(甚至部分location.search)里面的参数信息。但是,它重新定义了参数的名称,甚至参数的个数。也可以理解为,它重新进行了一次独立的参数匹配。

历史兼容

在更早期的react router@v5版本里面的话,这个useMatch()对应的叫做useRouteMatch()。参考文章:

这里提到了两个参数:endcaseSensitive。使用方式举例:

const match = useMatch({
    caseSensitive: false,  // 大写小写
    end: true,             // 完全严格匹配
    path: "/post/:id3/:title3",
});
console.log(match);

具体待后续文章讨论。

结语

如果当前的路由的path属性,定义的参数不满足要求的时候,才会用得到useMatch()进行二次匹配。否则,使用useParams()挺好的。

对于location里面?后面的search信息,目前的结论是这样的:建议使用useSearchParams()进行匹配。它对useMatch()有作用力,但是作用的具体效果未知。

苏南大叔的更多react经验文章,请参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react