React Router v4 - Как получить текущий маршрут?


182

Я хотел бы, чтобы отобразить titleв <AppBar />том , что каким - то образом передается из текущего маршрута.

В React Router v4, как можно <AppBar />было бы передать текущий маршрут в его titleпропеллер?

  <Router basename='/app'>
    <main>
      <Menu active={menu} close={this.closeMenu} />
      <Overlay active={menu} onClick={this.closeMenu} />
      <AppBar handleMenuIcon={this.handleMenuIcon} title='Test' />
      <Route path='/customers' component={Customers} />
    </main>
  </Router>

Есть ли способ передать пользовательское название от обычая propна <Route />?


Возможный дубликат « Как получить текущий маршрут в
activ

Ответы:


76

В версии 5.1 реакции-маршрутизатора есть ловушка, называемая useLocation , которая возвращает объект текущего местоположения. Это может быть полезно в любое время, когда вам нужно знать текущий URL.

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

function HeaderView() {
  let location = useLocation();
  console.log(location.pathname);
  return <span>Path : {location.pathname}</span>
}


7
Обратите внимание, что это можно использовать только внутри DOM маршрутизатора (т. Е. Компонентов chid, но не в классе / функциональном компоненте, где используется маршрутизатор). Это может быть очевидно, но не новичку, как я :-) Я все время получал ошибку "useContext не определен"
BennyHilarious

также это не будет работать, если использовался маршрутизатор redirect. это будет читать путь до перенаправления
Sonic Soul

спасибо за этот ответ ...
Bellabelle

212

В реагирующем маршрутизаторе 4 текущий маршрут находится в - this.props.location.pathname. Просто получите this.propsи проверьте. Если вы все еще не видите, location.pathnameто вы должны использовать декоратор withRouter.

Это может выглядеть примерно так:

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

const SomeComponent = withRouter(props => <MyComponent {...props}/>);

class MyComponent extends React.Component {
  SomeMethod () {
    const {pathname} = this.props.location;
  }
}

14
пожалуйста, обратите внимание, что это не всегда так: с реакцией router4, если ваш компонент отображается на более высоком уровне относительно некоторых вложенных маршрутов (который расширяет путь позже), location.pathname внутри WithRouter будет отличаться отwindow.location.pathname
maioman

3
Как мы можем получить это программно вне компонента React?
trusktr

78

Если вы используете РЕАКТ шаблонов, где конец вашего реагирующий файл выглядит следующим образом : export default SomeComponentвам нужно использовать компонент высшего порядка (часто называемый как «HOC»), withRouter.

Во-первых, вам нужно импортировать withRouterтак:

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

Далее вы захотите использовать withRouter . Вы можете сделать это, изменив экспорт вашего компонента. Вероятно, вы хотите изменить с export default ComponentNameна export default withRouter(ComponentName).

Тогда вы можете получить маршрут (и другую информацию) из реквизита. В частности, location, match, и history. Код для выделения пути:

console.log(this.props.location.pathname);

Хорошая рецензия с дополнительной информацией доступна здесь: https://reacttraining.com/react-router/core/guides/philosophy


Но как вы получите полный URL?
Tessaracter

18

Вот решение, использующее history Подробнее

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

внутри роутера

<Router>
   {history.location.pathname}
</Router>

3
Для тех из нас, кто находится на функциональном пути реакции, этот ответ имеет смысл. Те, this.props....кто просто шум для наших ушей.
Хофи

17

В реакции-маршрутизаторе v5 есть ловушка под названием useLocation , нет необходимости в HOC или других вещах, она очень лаконична и удобна.

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

const ExampleComponent: React.FC = () => {
  const location = useLocation();  

  return (
    <Router basename='/app'>
      <main>
        <AppBar handleMenuIcon={this.handleMenuIcon} title={location.pathname} />
      </main>
    </Router>
  );
}

Этот ответ должен быть оценен гораздо выше. Использование хука намного проще и интуитивнее, чем эти другие решения (если на RR v5)
BrDaHa

10

Я думаю, что автор React Router (v4) только что добавил это с помощью Router HOC, чтобы успокоить определенных пользователей. Тем не менее, я считаю, что лучше всего использовать рендер-проп и создать простой компонент PropsRoute, который пропускает эти реквизиты. Это легче проверить, поскольку вы не «подключаете» компонент, как это делает withRouter. Имейте кучу вложенных компонентов, завернутых в withRouter, и это не будет весело. Еще одним преимуществом является то, что вы также можете использовать этот проход через любые реквизиты, которые вы хотите на маршруте. Вот простой пример использования рендера проп. (в значительной степени точный пример с их веб-сайта https://reacttraining.com/react-router/web/api/Route/render-func ) (src / components / route / props-route)

import React from 'react';
import { Route } from 'react-router';

export const PropsRoute = ({ component: Component, ...props }) => (
  <Route
    { ...props }
    render={ renderProps => (<Component { ...renderProps } { ...props } />) }
  />
);

export default PropsRoute;

Использование: (обратите внимание, чтобы получить параметры маршрута (match.params), вы можете просто использовать этот компонент, и они будут переданы для вас)

import React from 'react';
import PropsRoute from 'src/components/routes/props-route';

export const someComponent = props => (<PropsRoute component={ Profile } />);

Также обратите внимание, что таким способом вы можете передать любые дополнительные реквизиты, которые захотите.

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />

3
Можно ли как-нибудь превратить это решение в кодекс? Я хочу использовать более правильное решение, но я действительно не понимаю, как реализовать.
LAdams87

7

Имеет Con Posidielov сказал, текущий маршрут присутствует вthis.props.location.pathname .

Но если вы хотите сопоставить более конкретное поле, например ключ (или имя), вы можете использовать matchPath, чтобы найти исходную ссылку на маршрут.

import { matchPath } from `react-router`

const routes = [{
  key: 'page1'
  exact: true,
  path: '/page1/:someparam/',
  component: Page1,
},
{
  exact: true,
  key: 'page2',
  path: '/page2',
  component: Page2,
},
]

const currentRoute = routes.find(
  route => matchPath(this.props.location.pathname, route)
)

console.log(`My current route key is : ${currentRoute.key}`)

0

Добавить

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

Затем измените экспорт компонентов

export default withRouter(ComponentName)

Затем вы можете получить доступ к маршруту непосредственно внутри самого компонента (не затрагивая ничего в вашем проекте), используя:

window.location.pathname

Протестировано в марте 2020 года с: «версия»: «5.1.2»


Не уверен насчет этого. Конечно, он дает текущий путь, но это не изменится, если я перейду на новую страницу.
Алекс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.