37

How to check if generic react-router path matches current location pathname?

react-router path: /Movies/:id
location.pathname: /Movies/56fa7446bae6eb301e5937f3

I want to use route paths with menu buttons, to set class="active".

EDIT:

To clarify, paths in my app look like:

/Movies/56fa7/watch

and not like:

/Movies/watch/56fa7

How do I check if the former route is active?

Is it doable without <Link> component?

/Movies/56fa7/watch is arbitrary after /Movies, and <Link> obviously can't be pointed to an arbitrary location. So let's ignore <Link> for a moment:

Is there a standalone function or property in react-router that checks if /Movies/:id/watch is active?

Luka
  • 539
  • 1
  • 6
  • 10

5 Answers5

43

According to the docs, you could use matchPath function which takes two arguments:

  1. pathname you want to match (String).
  2. options (Object) or path (String) to match against.

If matched it will return an object of this shape:

{
  path, // the path used to match
  url, // the matched portion of the URL
  isExact, // whether or not we matched exactly
  params
}

Otherwise you'll get null.

To make use of it in your components you could simply do:

import { matchPath } from 'react-router';

// ...

render () {
  const isMovieWatchPathActive = !!matchPath(
    this.props.location.pathname, 
    '/Movies/:id/watch'
  ); 

  // ...
}

Hope it'll help someone.

n1stre
  • 5,856
  • 4
  • 20
  • 41
5

As of React Router v4 (March 2017):

I'm a bit late to the party, but hopefully this will help anyone with the same question. When a component is rendered through a Route, certain props are passed to it. These props can be used to determine which route is active.

In a component rendered by a Route, you can use this.props.match.url to get the actual URL requested by the browser, and you can use this.props.match.path to get the path pattern for the current route.

Check working example here: https://codesandbox.io/s/20o7q0483j

Docs related to this are available here: https://reacttraining.com/react-router/web/api/Route/Route-props

Shishir
  • 2,488
  • 20
  • 22
5

use this

import { matchPath } from "react-router";

const match = matchPath("/users/123", {
  path: "/users/:id",
  exact: true,
  strict: false
});
rohit
  • 199
  • 4
  • 13
0

Check out the Link's property: activeStyle or activeClassName. They are supposed to automatically set the link to active when route matches. See the example: https://github.com/reactjs/react-router-tutorial/tree/master/lessons/05-active-links

wwg
  • 1
  • 2
  • Yes, but they will only match exact pathnames. I need solution for general paths used in components. – Luka Mar 29 '16 at 19:33
  • I see, although when child matches, the parent should be active also. https://github.com/reactjs/react-router-tutorial/tree/master/lessons/07-more-nesting – wwg Mar 29 '16 at 20:02
  • See EDIT in the original question. – Luka Mar 30 '16 at 12:23
  • This has changed in v4, see https://stackoverflow.com/a/43081982/2333665 – asliwinski May 29 '18 at 09:10
0

React Router V6

MatchPath in V6 is different from the other version, below is an example of how to use it.

publicRoutes.forEach(({ path }) => {
      if (!!matchPath(path, location.pathname)) {
         ...
      }
    });

Below is the link to matchPath documentation and link to another stackoverflow post with more details, hope this helps! :)

Gerald H
  • 454
  • 4
  • 13