React-router v6:获取当前路由的路径模式

cas*_*hol 100 javascript reactjs react-router react-router-dom

是否可以获得当前匹配路由的路径模式?例子:

<Route
    path=":state/:city*"
    element={
        <Page />
    }
/>
Run Code Online (Sandbox Code Playgroud)
<Route
    path=":state/:city*"
    element={
        <Page />
    }
/>
Run Code Online (Sandbox Code Playgroud)

我知道我可以用来useMatch检查当前位置是否与特定路径模式匹配,但组件必须知道路径模式是什么。

小智 71

我用react-router v6制作了一个自定义钩子useCurrentPath来获取当前的路由路径,它对我有用

如果当前路径名是/members/5566我将得到路径/members/:id

import { matchRoutes, useLocation } from "react-router-dom"

const routes = [{ path: "/members/:id" }]

const useCurrentPath = () => {
  const location = useLocation()
  const [{ route }] = matchRoutes(routes, location)

  return route.path
}
Run Code Online (Sandbox Code Playgroud)

function MemberPage() {
  const currentPath = useCurrentPath() // `/members/5566` -> `/members/:id`
   
  return <></>
}
Run Code Online (Sandbox Code Playgroud)

参考

https://reactrouter.com/en/v6.3.0/api#matchroutes

  • 这对我来说非常有用。定制挂钩是个人喜好。然而,“useLocation”+“matchRoutes”就是答案。 (5认同)
  • 这似乎不适用于具有相对路径的嵌套路由。例如,当 `location.pathname` 是 `"/users/123/profile"` 但 `routes[0].path` 是 `"profile"` 时,因为嵌套在 `"users/:id"` 下。你有解决办法吗? (2认同)

m.w*_*ona 11

我不确定它是否完全解决了您的用例,但就我而言,我使用了useLocation和的组合useParams。这是代码:

import React from 'react';
import { useLocation, useParams } from 'react-router-dom';
import type { Location, Params } from 'react-router-dom';

/**
 * Function converts path like /user/123 to /user/:id
 */
const getRoutePath = (location: Location, params: Params): string => {
  const { pathname } = location;

  if (!Object.keys(params).length) {
    return pathname; // we don't need to replace anything
  }

  let path = pathname;
  Object.entries(params).forEach(([paramName, paramValue]) => {
    if (paramValue) {
      path = path.replace(paramValue, `:${paramName}`);
    }
  });
  return path;
};

export const Foo = (): JSX.Element => {
  const location = useLocation();
  const params = useParams();
  const path = getRoutePath(location, params);

  (...)
};
Run Code Online (Sandbox Code Playgroud)

  • 当路径的某些部分具有相同的值(例如“/user/1/badge/1/comment/1”)时,此解决方案将会中断。虽然这种情况并不常见,但该解决方案仍然不是普遍可靠的。 (6认同)

小智 8

从 a 的上下文中,Route您可以通过文档path中列出的几种方法来获取。

我的问题略有不同,因为我需要path外部的上下文Route,并得出了以下也应该适合您的解决方案:

import {
    matchPath,
    useLocation
} from "react-router-dom";

const routes = [ ':state/:city', ...otherRoutes ];

function usePathPattern() {

    const { pathname } = useLocation();

    return matchPath( pathname, routes )?.path;
}
Run Code Online (Sandbox Code Playgroud)

  • 您的文档链接指向 v5 文档,而不是 v6 文档,因此没有帮助。 (14认同)

小智 5

这对我来说很容易

首先从react-router-dom导入uselocation

import { useLocation } from "react-router-dom"
Run Code Online (Sandbox Code Playgroud)

然后

const location = useLocation();
console.log(location.pathname);
Run Code Online (Sandbox Code Playgroud)

  • 这给出了文字路径而不是路径模式。 (23认同)

小智 -3

import { useMatch, Route, Routes } from "react-router-dom";

<Routes>
   <Route path="/" element={<Element1 match={useMatch("/")} />}  >
      <Route path=":id" element={<Element2 match={useMatch("/:id")} />}  />
   </Route>
</Routes>
Run Code Online (Sandbox Code Playgroud)