react-router-dom中的match是个很重要的点, 而match中的urlpath又很难区分, 今天来看一下…

前言


在之前写毕设的过程中, 一直在用match这个对象, 但是对于

  • match.path
  • match.url

这两个东西总是分不清, 很困惑…

Route的源码分析章节, 对这两者有了简单的了解, 但并不是很深刻. 今天下定决心, 彻底搞清楚这两个参数.

分析


字面量

首先通过字面量来分析两者区别:

何为字面量?

这里的字面量就是pathurl两者的中文语义, 分别是这样的:

url 网址
path 路径

哎, 瞎猫遇上死耗子, 通过中文并不能看出任何差别. 那么, 接着往下看

官网解释

打开react-router官网, 看到react-router官方对两者的解释:

  • path - (string) The path pattern used to match. Useful for building nested s
  • url - (string) The matched portion of the URL. Useful for building nested s

google翻译一下:

  • path - 用于匹配的路径模式, 通常用来构建嵌套的Route.
  • url - URL的匹配模式, 通常用来构建嵌套Link.

🆗, 这是官方的解释, 好像并没有什么卵用? 相信没有看过源码的话, 看到这个肯定是一脸懵逼? 继续往下看:

个人解读

match.path

首先, 贴一张Gayhubreact-router的源码部分截图:

react-router部分源码

通过遍历paths数组path, 看到黄色标记部分, 直接将符合条件的path赋值给match, 那么, 可以轻松的得出这样的结论:

match.path === Route.props.path

也就是说, matchpath参数, 其实就是将匹配成功的Route的pathprops原封不动的传递过去.

OK, 可能有点晦涩, 看一个例子:

1
2
3
4
5
6
7
8
9
// 扮演 `location.pathname`
const pathname = '/user/duan/profile/19980808';

// 对应的 `嵌套路由`
<BrowserRouter>
<Switch>
<Route path="/user/:name/profile/:secret" component={xxx}>
<Switch>
<BrowserRouter>

那么此时, match.path就等于/user/:name/profile/:secret.

match.url

同样, 引用上面的截图中的部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...

const { regexp, keys } = compilePath(path, {
end: exact,
strict,
sensitive
});
const match = regexp.exec(pathname);

...

const [url, ...values] = match;
const isExact = pathname === url;

...

return {
url: path === "/" && url === "" ? "/" : url,
};

通过调用path-to-regexp库, 将path转化为RegExp对象, 并调用regexp.exec()方法, 得到一个execMatch, 长这样:

exec到的match对象

该对象的第一个参数, 就是匹配后的url, 由此可以得出:

url = path.match(regexp)[0]

结论

经过上面的要点分析, 可以很轻松的看出来:

  • match.path只是一种匹配模式, 就是告诉你根据这种模式去匹配.
  • match.url则是match.path执行精确匹配后的具体路径

一般情况下:

  • match.path = Route.props.path
  • match.url = location.pathname