React Router v4 - Як отримати поточний маршрут?


180

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

Як реалізувати маршрутизатор React 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 />?


Відповіді:


74

У випуску 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>
}



6
Зауважте, це може використовуватися тільки всередині маршрутизатора DOM (тобто компоненти chid, а не в класі / функціональному компоненті, де використовується маршрутизатор). Це може бути очевидним, але не для новачків, як я :-) Я отримував весь час помилку "useContext не визначено"
BennyHilarious

також це не буде працювати, якщо redirectбув використаний маршрутизатор . це буде читати шлях перед перенаправленням
Sonic Soul

дякую за цю відповідь ...
bellabelle

211

У реакційному маршрутизаторі 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
зауважте, що це не завжди відповідає дійсності: з react-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 Read more

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, який передає ці реквізити. Це простіше перевірити, оскільки ви не "з'єднуєте" компонент, як це робить зRouter. Майте купу вкладених компонентів уRouter, і це не буде весело. Ще одна перевага полягає в тому, що ви також можете використовувати цей прохід через будь-який реквізит, який ви хочете до маршруту. Ось простий приклад використання рендерінга. (майже точний приклад з їх веб-сайту https://reacttraining.com/react-router/web/api/Route/render-func ) (src / компоненти / маршрути / реквізит-маршрут)

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"


Не впевнений у цьому. Звичайно, це дає поточне ім'я шляху, але це не зміниться, якщо я перейду на нову сторінку.
alex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.