Как получить доступ к `match.params` вне маршрутизатора?

#react-router-v4

#react-router-v4

Вопрос:

Я пытаюсь получить match.params для контейнера моего приложения.

Я пробовал использовать withRouter(AppContainer) и match.params всегда было пусто.

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

Перейдите к /foo/bar .
Я ожидаю, что match.params in AppContainer будет { path1: 'foo', path2: 'bar'} , но они всегда есть {} .

Я думаю, это потому, что AppContainer находится за пределами маршрутов, которые имеют интересующие меня параметры маршрута.

Итак, мне интересно, есть ли другой способ, который я мог бы сделать здесь, чтобы я мог получить параметры маршрута внутри AppContainer . В идеале без использования хранилища redux.

Ответ №1:

Короче говоря, нет способа использовать match .

Мне кажется, единственный способ сделать это — использовать 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);
  

Ответ №2:

Если кто-то ищет, как решить это с помощью перехватов, вы можете просто использовать перехват useRouteMatch(). Это даже немного чище.

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

const Test = () => {

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

}
  

Комментарии:

1. Для тех, кто использует версию 6: reactrouter.com/docs/en/v6/upgrading / …