React路由,useMatch获取参数,和useParams有何区别?
发布于 作者:苏南大叔 来源:程序如此灵动~
本文讲述React路由提供的useMatch()钩子,它和useParams()钩子很类似,都可以用来获得隐藏在路径中的参数信息。那么,两者有什么区别和联系呢?这就是本文要考虑的问题。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0,create-react-app@5.0.1,react-router-dom@6.27.0,react@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 );
//...
}对比测试代码

完整测试代码:
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。两者不冲突,没关系。

或者说,钩子useMatch()也能取得隐藏在location.pathname(甚至部分location.search)里面的参数信息。但是,它重新定义了参数的名称,甚至参数的个数。也可以理解为,它重新进行了一次独立的参数匹配。
历史兼容
在更早期的react router@v5版本里面的话,这个useMatch()对应的叫做useRouteMatch()。参考文章:
这里提到了两个参数:end和caseSensitive。使用方式举例:
const match = useMatch({
caseSensitive: false, // 大写小写
end: true, // 完全严格匹配
path: "/post/:id3/:title3",
});
console.log(match);具体待后续文章讨论。
结语
如果当前的路由的path属性,定义的参数不满足要求的时候,才会用得到useMatch()进行二次匹配。否则,使用useParams()挺好的。
对于location里面?后面的search信息,目前的结论是这样的:建议使用useSearchParams()进行匹配。它对useMatch()有作用力,但是作用的具体效果未知。
苏南大叔的更多react经验文章,请参考: