Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-router v6: get path pattern for current route

Is it possible to get the path pattern for the currently matched route? Example:

<Route
    path=":state/:city*"
    element={
        <Page />
    }
/>
// Page.jsx

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

I know I can use useMatch to check if the current location matches a specific path pattern, but then the component has to know what the path pattern is.

like image 747
caseyjhol Avatar asked Feb 18 '21 18:02

caseyjhol


People also ask

How do you find the current path in react v6 router?

Use the useLocation() hook to get the current route with React Router, e.g. const location = useLocation() . The hook returns the current location object. For example, you can access the pathname as location. pathname .

How do you find the current path in react?

Since React is based on regular JavaScript, you can access the location property on the window interface. To get the full path of the current URL, you can use window. location. href , and to get the path without the root domain, access window.

How do I listen to route changes in react v6 router?

Use your router and pass your history object to it. In a component you want to listen to location changes on, import your history object and invoke the listen callback as you did previously. import history from '../myHistory'; ...

How do I get the current route in react router?

Getting current route using hooks With the react router v5, we can use the useLocation () hook to get the current route path in a router component.

How to get the current route path in a Router component?

With the react router v5, we can use the useLocation () hook to get the current route path in a router component. In the above code, we first imported the useLocation hook from the react-router-dom package, then inside the About component we accessed the current route using location.pathname property.

Does react router V6 pick the best element for a route?

This is not the case with React Router v6. It picks one of the best elements from the React Router library called Outlet to render any matching children for a particular route. To start, import the Outlet from the react-router-dom library:

What is the difference between path and element in react route?

It has a prop called path which always matches the current URL of the application. The second required prop is called element that tells the Route component when a current URL is encountered and which React component to be rendered. The element keyword here is also a new addition.


Video Answer


5 Answers

I'm not sure if it resolves your use case fully but in my case I used combination of useLocation and useParams. Here is the 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);

  (...)
};
like image 142
m.wrona Avatar answered Oct 17 '22 09:10

m.wrona


I made a custom hook useCurrentPath with react-router v6 to get the current path of route, and it work for me

If the current pathname is /members/5566 I will get path /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
}

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

Reference

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

like image 32
Futian Shen Avatar answered Oct 17 '22 10:10

Futian Shen


From within the context of a Route you can get the path via several methods layed out in the docs.

My issue was slightly different in that I needed the path outside the context of the Route and came to the below solution that should also work for you:

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

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

function usePathPattern() {

    const { pathname } = useLocation();

    return matchPath( pathname, routes )?.path;
}
like image 4
James M Avatar answered Oct 17 '22 10:10

James M


this is works for me easily

first of all import uselocation from react-router-dom

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

then

const location = useLocation();
console.log(location.pathname);
like image 1
MD Mahmudul Hasan Avatar answered Oct 17 '22 11:10

MD Mahmudul Hasan


This seems to work with what they actually export as of 6.2.1, however it uses a component they export as UNSAFE_

import { UNSAFE_RouteContext } from 'react-router-dom';

const reconstructPath = (matches) =>
  matches
    .map(({ route: { path } }) =>
      path.endsWith('/*') ? path.slice(0, -1) : path ? path + '/' : ''
    )
    .join('');

const findLastNode = (node) =>
  node.outlet ? findLastNode(node.outlet.props.value) : node;

const usePathPattern = () =>
  reconstructPath(
    findLastNode(React.useContext(UNSAFE_RouteContext)).matches
  );
like image 1
RichN Avatar answered Oct 17 '22 10:10

RichN