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

React Router里面,测算当前路径匹配到了哪个路由,是个很重要的事情。因为可以通过自定义的路由数据获得很多额外的配置信息,本文内苏南大叔将要讲述的是matchRoutes()函数,它的功用和useMatches()这个钩子比较相似。但是,两者也有不同。可以根据实际的需求,来选择合适的钩子/函数。

苏南大叔:React路由,如何理解函数matchRoutes?对比useMatches - matchRoutes全新匹配
React路由,如何理解函数matchRoutes?对比useMatches(图3-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0create-react-app@5.0.1react-router-dom@6.27.0react@18.3.1matchRoutes()useMatches()的功用类似,主要反馈了在全新的甚至毫不相关的路由条件下,可以匹配到那几条路由规则。

前文回顾

回顾一下相关的钩子函数:

matchRoutes

本文讲述的函数叫做matchRoutes(),值得注意的是:它没有以use开头,这意味着它是个普通的函数,并不是一个钩子。并不是一个在react世界里面遍地飞舞的钩子!!!

其官方文档:

matchRoutes runs the route matching algorithm for a set of routes against a given location to see which routes (if any) match. If it finds a match, an array of RouteMatch objects is returned, one for each route that matched.

大意就是:可以给出一个新的路由配置数据(原来的旧数组也可以),和一个新的location对象(用当前的location也可以),两者重新组合配对,最终返回一个新的匹配结果。

测试代码

如果使用旧的路由配置数组,使用当前location的话,那么就是再次重新匹配了一次。和useMatches()的效果差不多。当然,返回值也是有区别的。例子改编自上一篇文章:

routes.js:

import React from "react";
import Post from "./Post";
import Detail from "./Detail";
const routers = [
  {
    path: "/detail/:id",
    element: <Detail />,
    tag: "独立详情页",
  },
  {
    path: "/post/",
    element: <Post />,
    tag: "文章页",
    children: [
      {
        path: ":id",
        element: <Detail />,
        tag: "嵌套详情页",
      },
    ],
  },
];
export default routers;

苏南大叔:React路由,如何理解函数matchRoutes?对比useMatches - 路由配置信息
React路由,如何理解函数matchRoutes?对比useMatches(图3-2)

src/Post.js:

import { useMatches,Outlet } from "react-router-dom";
export default () => {
  const matches = useMatches();
  console.log(matches);
  return (
    <div>
      Post组件:useMatches()
      <Outlet />
    </div>
  );
};

src/Detail.js:

import { useMatches,useLocation,matchRoutes } from "react-router-dom";
import routes from "./routes";
export default () => {
  const location = useLocation();
  const matched = matchRoutes(routes, location);
  console.log(matched);
  return <div>Detail组件:matchRoutes(routes, location)</div>;
}; 

重大区别

这个matchRoutes()返回值里面,带出了个.route属性,它才是重要的角色。它可以完全反馈匹配的路由配置数组信息。也就是说配置在【路由数组里面的自定义属性,是可以取到的】!!!

访问同一个地址,/post/123,对比输出。

const matches = useMatches();
console.log(matches);

输出:

[
    {
        "id": "1",
        "pathname": "/post",
        "params": {
            "id": "123"
        },
        "data":undefined,
        "handle":undefined,
    },
    {
        "id": "1-0",
        "pathname": "/post/123",
        "params": {
            "id": "123"
        },
        "data":undefined,
        "handle":undefined,
    }
]
const location = useLocation();
const matched = matchRoutes(routes, location);
console.log(matched);

输出:

[
    {
        "params": {
            "id": "123"
        },
        "pathname": "/post",
        "pathnameBase": "/post",
        "route": {
            "path": "/post/",
            "element": {
                "key": null,
                "ref": null,
                "props": {},
                "_owner": null,
                "_store": {}
            },
            "tag": "文章页",
            "children": [
                {
                    "path": ":id",
                    "element": {
                        "key": null,
                        "ref": null,
                        "props": {},
                        "_owner": null,
                        "_store": {}
                    },
                    "tag": "嵌套详情页"
                }
            ]
        }
    },
    {
        "params": {
            "id": "123"
        },
        "pathname": "/post/123",
        "pathnameBase": "/post/123",
        "route": {
            "path": ":id",
            "element": {
                "key": null,
                "ref": null,
                "props": {},
                "_owner": null,
                "_store": {}
            },
            "tag": "嵌套详情页"
        }
    }
]

苏南大叔:React路由,如何理解函数matchRoutes?对比useMatches - 结果对比
React路由,如何理解函数matchRoutes?对比useMatches(图3-3)

路由方式

useMatches()这个钩子里面,只能使用createXxxRouter()+RouterProvider的方式。但是这个限制,在matchRoutes()里面是完全不存在的。

理论上来说,matchRoutes()和当前的路由信息是完全没有关系的。它所使用的匹配规则是它的第一个参数。所以,两种路由写法,其实都和matchRoutes()完全没有关系。所以,也可以这么说,支持两种路由写法了。

扩展代码

如果像 useMatches()一样,取最最最符合当前地址的那条路由信息的话。可以这样获得:

function match(routes, location){
  const matched = matchRoutes(routes, location);
  const n = matched.length;
  if (n > 0) return matched[n - 1].route;
  else return null;
}

表格对比

useMatches()matchRoutes()
没有参数传参全新匹配
可获得.handle里面的自定义属性可直接获得自定义属性

结语

useMatches(),还是和当前的路由匹配规则严格匹配的,其匹配的结果也是严格安装模版走的。如果把条件放松,规则和地址,都可以推倒重来的话,使用的就是matchRoutes()了。其路由匹配结果比较自由,可以显示自定义的属性。

更多苏南大叔的react经典文章,可以参考:

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

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

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

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