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
经验文章,请参考:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。