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>
}

vr12
источник
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

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

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

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

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

<Router>
   {history.location.pathname}
</Router>
Ваэль Мохамед BETTAYEB
источник
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 } />
hal9000
источник
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}`)
Rasta_boy
источник
0

Добавить

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

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

export default withRouter(ComponentName)

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

window.location.pathname

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

Шивон
источник
Не уверен насчет этого. Конечно, он дает текущий путь, но это не изменится, если я перейду на новую страницу.
Алекс