React Router v4 - Làm thế nào để có được tuyến đường hiện tại?


180

Tôi muốn hiển thị một titletrong <AppBar />đó bằng cách nào đó được truyền từ tuyến đường hiện tại.

Trong React Router v4, làm thế nào <AppBar />để có thể đưa tuyến đường hiện tại đi vào chỗ dựa của nó 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>

Có cách nào để vượt qua một tiêu đề tùy chỉnh từ một tùy chỉnh proptrên <Route />?


Câu trả lời:


74

Trong bản phát hành 5.1 của bộ định tuyến phản ứng, có một cái móc gọi là useLocation , trả về đối tượng vị trí hiện tại. Điều này có thể hữu ích bất cứ lúc nào bạn cần biết URL hiện tại.

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

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


6
Xin lưu ý rằng điều này chỉ có thể được sử dụng bên trong Bộ định tuyến DOM (nghĩa là các thành phần chid, không phải trong thành phần lớp / chức năng nơi Bộ định tuyến được sử dụng). Nó có thể rõ ràng nhưng không phải với một người mới như tôi :-) Tôi đã nhận được tất cả các lỗi "useContext không xác định"
BennyHilarious

Ngoài ra, điều này sẽ không hoạt động nếu một bộ định tuyến redirectđã được sử dụng. điều này sẽ đọc đường dẫn trước khi chuyển hướng
Sonic Soul

cảm ơn bạn vì câu trả lời này ...
bellabelle

211

Trong bộ định tuyến phản ứng 4, tuyến đường hiện tại nằm trong - this.props.location.pathname. Chỉ cần nhận this.propsvà xác minh. Nếu bạn vẫn không thấy location.pathnamethì bạn nên sử dụng trang tríwithRouter .

Cái này có thể trông giống như thế này:

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

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

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

14
xin lưu ý rằng điều này không phải lúc nào cũng đúng: với Reac-router4, nếu thành phần của bạn được hiển thị ở mức độ cao hơn đối với một số tuyến đường lồng nhau (mở rộng đường dẫn sau), location.pathname bên trong WithRouter sẽ khác vớiwindow.location.pathname
maioman

3
Làm thế nào để chúng ta có được nó theo chương trình bên ngoài thành phần React?
trusktr

78

Nếu bạn đang sử dụng các mẫu phản ứng, trong đó phần cuối của tệp phản ứng của bạn trông như thế này: export default SomeComponentbạn cần sử dụng thành phần bậc cao hơn (thường được gọi là "HOC") , withRouter.

Trước tiên, bạn sẽ cần nhập withRouternhư vậy:

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

Tiếp theo, bạn sẽ muốn sử dụng withRouter . Bạn có thể làm điều này bằng cách thay đổi xuất thành phần của bạn. Có khả năng bạn muốn thay đổi từ export default ComponentNamethành export default withRouter(ComponentName).

Sau đó, bạn có thể nhận được tuyến đường (và thông tin khác) từ đạo cụ. Cụ thể, location, match, và history. Mã để nhổ tên đường dẫn sẽ là:

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

Một bài viết tốt với thông tin bổ sung có sẵn ở đây: https://reacttraining.com/react-router/core/guides/phil Triết


Nhưng làm thế nào để bạn có được url hoàn chỉnh?
Tessaracter

18

Đây là một giải pháp sử dụng history Đọc thêm

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

bên trong bộ định tuyến

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

3
Đối với những người trong chúng ta trên con đường chức năng phản ứng, câu trả lời này có ý nghĩa nhất. Những this.props....gì chỉ là tiếng ồn đến tai chúng ta.
KhoPhi

17

Có một cái móc gọi là useLocation trong Reac -router v5, không cần HOC hay những thứ khác, nó rất ngắn gọn và tiện lợi.

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

Câu trả lời này nên được đánh giá cao hơn nhiều. Sử dụng hook rất dễ dàng và trực quan hơn nhiều so với các giải pháp khác này (nếu trên RR v5)
BrDaHa

10

Tôi nghĩ rằng tác giả của React Router (v4) chỉ cần thêm rằng withRouter HOC để xoa dịu một số người dùng nhất định. Tuy nhiên, tôi tin rằng cách tiếp cận tốt hơn là chỉ sử dụng render prop và tạo một thành phần propsRoute đơn giản để vượt qua các đạo cụ đó. Điều này dễ kiểm tra hơn vì bạn không "kết nối" thành phần như vớiRouter. Có một loạt các thành phần lồng nhau được bọc trongRouter và nó sẽ không vui. Một lợi ích khác là bạn cũng có thể sử dụng đường chuyền này thông qua bất kỳ đạo cụ nào bạn muốn đến Tuyến đường. Đây là ví dụ đơn giản sử dụng render prop. (khá nhiều ví dụ chính xác từ trang web của họ https://reacttraining.com/react-router/web/api/Route/render-func ) (src / thành phần / tuyến / đạo cụ-tuyến đường)

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;

cách sử dụng: (thông báo để nhận thông số tuyến đường (match.params) bạn chỉ có thể sử dụng thành phần này và chúng sẽ được chuyển cho bạn)

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

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

cũng lưu ý rằng bạn có thể vượt qua bất kỳ đạo cụ bổ sung nào bạn muốn theo cách này

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

3
Có cách nào chúng ta có thể biến giải pháp này thành một codepen không? Tôi muốn sử dụng giải pháp chính xác hơn nhưng tôi thực sự không hiểu cách thực hiện.
LAdams87

7

Con Posidielov cho biết, các tuyến đường hiện tại là hiện tại this.props.location.pathname.

Nhưng nếu bạn muốn khớp một trường cụ thể hơn như khóa (hoặc tên), bạn có thể sử dụng matchPath để tìm tham chiếu tuyến ban đầu.

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

Thêm vào

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

Sau đó thay đổi xuất thành phần của bạn

export default withRouter(ComponentName)

Sau đó, bạn có thể truy cập tuyến đường trực tiếp trong chính thành phần (mà không cần chạm vào bất kỳ thứ gì khác trong dự án của bạn) bằng cách sử dụng:

window.location.pathname

Đã thử nghiệm vào tháng 3 năm 2020 với: "phiên bản": "5.1.2"


Không chắc chắn về điều này. Chắc chắn, nó đưa ra tên đường dẫn hiện tại, nhưng điều đó sẽ không thay đổi nếu tôi điều hướng đến một trang mới.
alex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.