45
votes

React-Router V6: Obtenez le modèle de chemin pour la route actuelle

est-il possible d'obtenir le modèle de chemin pour l'itinéraire actuellement adapté? Exemple:

// Page.jsx

function Page() {
    ...
    // usePathPattern doesn't actually exist
    const pathPattern = usePathPattern(); // pathPattern = ":state/:city*"
    ...
}
<Route
    path=":state/:city*"
    element={
        <Page />
    }
/>

Je sais que je peux utiliser usematch pour vérifier si l'emplacement actuel correspond à un modèle de chemin spécifique, mais alors le composant doit savoir quel est le modèle de chemin.


0 commentaires

10 Réponses :


-2
votes
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>

0 commentaires

4
votes

Dans le contexte d'un Route , vous pouvez obtenir le path via plusieurs méthodes présentées dans les docs .

Mon problème était légèrement différent en ce que j'avais besoin du path en dehors du contexte de la route Code> et est venu à la solution ci-dessous qui devrait également fonctionner pour vous:

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

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

function usePathPattern() {

    const { pathname } = useLocation();

    return matchPath( pathname, routes )?.path;
}


2 commentaires

Votre lien de documentation pointe vers les documents V5, pas les documents V6, et est donc inutile.


Documentation V6: reactrouter.com/docs/en/v6/utils/match-path



-2
votes

Ce n'est pas une réponse directe à la question, mais celles, qui ont trouvé cette question tout en essayant d'obtenir le params de l'objet Match , cela peut maintenant être fait avec le useParams crochet.

import { Route, Routes } from 'react-router-dom';
import { useParams } from 'react-router';

<Routes>
   <Route path="/:id" element={<MyComponent />} />
</Routes>

...

function MyComponent() {
  const { id } = useParams();

  return <div>{id}</div>
}

J'espère que c'est utile.


0 commentaires

0
votes

Vous ne pouvez pas pour le moment. Voici le travail autour:

<Route path="/:state" element={<LocationView />} />
<Route path="/:state/:city*" element={<LocationView city />} />

Je suppose que vous essayez de rendre le même composant sous plusieurs chemins. Au lieu de vérifier le modèle de chemin, vous pouvez ajouter un accessoire booléen au composant (dans ce cas City ) et vérifier si l'hélice est vraie.


0 commentaires

0
votes

Cela fonctionne facilement pour moi

​​Tout d'abord, importez-vous Uselocation à partir de React-Router-Dom

const location = useLocation();
console.log(location.pathname);

alors

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


1 commentaires

Cela donne au chemin littéral et non au modèle de chemin.



5
votes

Je ne sais pas si cela résout entièrement votre cas d'utilisation, mais dans mon cas, j'ai utilisé la combinaison de uselocation et useParams . Voici le code:

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);

  (...)
};


3 commentaires

Cette solution se casse lorsque des parties du chemin ont la même valeur, par exemple / utilisateur / 1 / badge / 1 / commentaire / 1 . Bien que ce soit un scénario rare, cette solution n'est toujours pas universellement fiable.


Mieux vaut utiliser reactrouter.com/docs/en/v6/api#matchRoutes Au lieu.


@ Hermanj.radtkeiii Le lien semble être brisé. Peut-être que vous voulez dire ce



1
votes

Cela semble fonctionner avec ce qu'ils exportent réellement au 6.2.1, mais il utilise un composant qu'ils exportent comme dangereux_ xxx


0 commentaires

13
votes

J'ai créé un crochet personnalisé usecurrentPath avec React-Router V6 pour obtenir le chemin d'accès actuel de l'itinéraire, et cela fonctionne pour moi

​​Si le chemin d'accès actuel est / membres / 5566 j'obtiendrai path / membres /: id

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


1 commentaires

Cela a très bien fonctionné pour moi. Le crochet personnalisé est une préférence personnelle. Cependant, uselocation + matchroutes est la réponse.



0
votes

J'ai écrit un crochet personnalisé à cet effet, car il ne semble pas être pris en charge OOB en ce moment:

Remarque: il n'est pas encore complètement testé. Alors utilisez avec prudence.

import { useLocation, useParams } from 'react-router';

export function useRoutePathPattern() {
  const routeParams = useParams();
  const location = useLocation();

  let routePathPattern = location.pathname;

  Object.keys(routeParams)
    .filter((paramKey) => paramKey !== '*')
    .forEach((paramKey) => {
      const paramValue = routeParams[paramKey];
      const regexMiddle = new RegExp(`\/${paramValue}\/`, 'g');
      const regexEnd = new RegExp(`\/${paramValue}$`, 'g');

      routePathPattern = routePathPattern.replaceAll(
        regexMiddle,
        `/:${paramKey}/`,
      );
      routePathPattern = routePathPattern.replaceAll(regexEnd, `/:${paramKey}`);
    });

  return routePathPattern;
}


0 commentaires

1
votes

Pour trouver l'itinéraire correspondant dans React-Router V6, vous devez utiliser la fonction MatchPath . Vous devrez stocker tous vos itinéraires dans une variable comme un tableau. Ensuite, vous pouvez parcourir tous les itinéraires et utiliser cette fonction pour trouver l'itinéraire correspondant. Soigneusement, car il correspondra à la première valeur de vérité, idéalement, vous devez les traverser dans le même ordre que vous les avez rendus.

Ce n'est pas une solution parfaite car elle ne peut pas gérer les itinéraires imbriqués à moins que vous ne stockiez ceux de la même variable.

Voici un exemple:

routes.ts

export function Header() {
  const route = useMatchedRoute();

  return <div>{route.name}</div>
}

app.tsx

import { matchPath } from 'react-router';

export function useMatchedRoute() {
  const { pathname } = useLocation();
  for (const route of routes) {
    if (matchPath({ path: route.path }, pathname)) {
      return route;
    }
  }
}


0 commentaires