Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access `match.params` outside of router?

I'm trying to get match.params for a container of my app.

I tried using withRouter(AppContainer) and match.params would always be empty.

// Routes
import React from 'react';
import { Route, Switch, Router } from 'react-router';
import { createBrowserHistory} from 'history';
import AppContainer from './app-container';
...
<Router history={createBrowserHistory()}>
  <AppContainer>
    <Switch>
      ...
      <Route exact path="/:path1/:path2" component={() => <div>hello</div>} />
      ...
    </Switch>
  </AppContainer>
</Router>

// app-container.js
import React from 'react';
import { withRouter } from 'react-router';
const AppContainer = (props) => {
  const { match } = props;
  console.log(match.params); // This will always be empty
  return <div>whatever</div>;
};
export default withRouter(AppContainer);

Navigate to /foo/bar. I expect match.params in AppContainer to be { path1: 'foo', path2: 'bar'}, but they are always {}.

I think it's because AppContainer is outside the routes that have route params that I'm interested in.

So, I'm wondering whether there's another way that I could do here so that I could get the route params inside AppContainer. Ideally without using a redux store.

like image 835
Ardo K Avatar asked Jan 27 '23 13:01

Ardo K


2 Answers

In short, there's no way to use match.

It seems to me the only way to do so is by using matchPath.

import { matchPath, withRouter } from 'react-router';

const Test = ({ location }) => {
  /*
  `matchPath` will return `null` if it doesn't match the path format.
  If it matches, it will return some object with parameters put into it
  nicely like `match.params`.
  */
  matchPath(location.search, { path: '/:path1/:path2' });
};
export default withRouter(Test);
like image 88
Ardo K Avatar answered Jan 29 '23 03:01

Ardo K


If someone is looking for how to solve this with hooks, you can simply use the useRouteMatch() hook. It is even a little cleaner.

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

const Test = () => {

const { params } = useRouteMatch('/:path1/:path2');

}
like image 21
bödvar Avatar answered Jan 29 '23 03:01

bödvar