React Router v4 - Bagaimana cara mendapatkan rute saat ini?

181

Saya ingin menampilkan titlein <AppBar />yang entah bagaimana dilewatkan dari rute saat ini.

Di React Router v4, bagaimana <AppBar />bisa mendapatkan rute saat ini dilewatkan ke titleprop itu?

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

Apakah ada cara untuk melewati judul kustom dari kustom proppada <Route />?

Raphael Rafatpanah
sumber
Kemungkinan rangkap dari Cara mendapatkan rute saat ini di react-router 2.0.0-rc5
Damjan Pavlica

Jawaban:

75

Dalam rilis 5.1-router bereaksi ada hook yang disebut useLocation , yang mengembalikan objek lokasi saat ini. Ini mungkin berguna kapan saja Anda perlu mengetahui URL saat ini.

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

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


ay12
sumber
6
Harap dicatat ini hanya dapat digunakan di dalam Router DOM (yaitu komponen chid, bukan di kelas / komponen fungsional di mana Router digunakan). Mungkin jelas tetapi tidak untuk seorang pemula seperti saya :-) Saya mendapatkan semua waktu kesalahan "useContext tidak terdefinisi"
BennyHilarious
juga ini tidak akan berfungsi jika router redirectdigunakan. ini akan membaca jalan sebelum arahan ulang
Sonic Soul
terima kasih atas jawaban ini ...
bellabelle
212

Dalam bereaksi router 4 rute saat ini di - this.props.location.pathname. Dapatkan this.propsdan verifikasi. Jika Anda masih tidak melihat location.pathnamemaka Anda harus menggunakan dekorator withRouter.

Ini mungkin terlihat seperti ini:

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

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

class MyComponent extends React.Component {
  SomeMethod () {
    const {pathname} = this.props.location;
  }
}
Con Posidielov
sumber
14
harap dicatat bahwa ini tidak selalu benar: dengan react-router4, jika komponen Anda diberikan pada tingkat yang lebih tinggi sehubungan dengan beberapa rute bersarang (yang memperpanjang jalur nanti) location.pathname di dalam WithRouter akan berbeda denganwindow.location.pathname
maioman
3
Bagaimana kita mendapatkannya secara terprogram di luar komponen Bereaksi?
trusktr
78

Jika Anda menggunakan templat reaksi, di mana akhir file reaksi Anda terlihat seperti ini: export default SomeComponentAnda perlu menggunakan komponen orde tinggi (sering disebut sebagai "HOC") withRouter,.

Pertama, Anda harus mengimpor withRouterseperti:

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

Selanjutnya, Anda akan ingin menggunakan withRouter . Anda dapat melakukan ini dengan mengubah ekspor komponen Anda. Kemungkinan Anda ingin berubah dari export default ComponentNamemenjadi export default withRouter(ComponentName).

Kemudian Anda bisa mendapatkan rute (dan informasi lainnya) dari properti. Secara khusus, location, match, dan history. Kode untuk memuntahkan pathname adalah:

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

Langgan yang baik dengan informasi tambahan tersedia di sini: https://reacttraining.com/react-router/core/guides/philosophy

lowcrawler
sumber
Tetapi bagaimana Anda mendapatkan url lengkap?
Tessaracter
18

Berikut ini adalah solusi menggunakan history Baca lebih lanjut

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

di dalam Router

<Router>
   {history.location.pathname}
</Router>
Wael Mohamed BETTAYEB
sumber
3
Bagi kita di jalur fungsional reaksi, jawaban ini paling masuk akal. Apa this.props....pun itu hanya kebisingan di telinga kita.
KhoPhi
17

Ada hook yang disebut useLocation di react-router v5, tidak perlu untuk HOC atau hal-hal lain, sangat ringkas dan nyaman.

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>
  );
}
Alexander Kim
sumber
Jawaban ini harus dinilai jauh lebih tinggi. Menggunakan kait jauh lebih mudah dan intuitif daripada solusi lain ini (jika pada RR v5)
BrDaHa
10

Saya pikir penulis React Router (v4) baru saja menambahkan bahwa withRouter HOC untuk menenangkan pengguna tertentu. Namun, saya percaya pendekatan yang lebih baik adalah dengan hanya menggunakan render prop dan membuat komponen PropsRoute sederhana yang melewati alat peraga tersebut. Ini lebih mudah untuk diuji karena Anda tidak "menghubungkan" komponen seperti withRouter. Memiliki banyak komponen bersarang yang dibungkus denganouter dan itu tidak akan menyenangkan. Manfaat lain adalah Anda juga dapat menggunakan pass ini melalui alat peraga apa pun yang Anda inginkan ke Rute. Inilah contoh sederhana menggunakan render prop. (cukup banyak contoh persis dari situs web mereka https://reacttraining.com/react-router/web/api/Route/render-func ) (src / komponen / rute / alat peraga-rute)

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;

penggunaan: (pemberitahuan untuk mendapatkan params rute (match.params) Anda cukup menggunakan komponen ini dan itu akan diteruskan untuk Anda)

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

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

juga perhatikan bahwa Anda dapat melewati alat peraga tambahan apa pun yang Anda inginkan dengan cara ini juga

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />
hal9000
sumber
3
Apakah ada cara untuk mengubah solusi ini menjadi codepen? Saya ingin menggunakan solusi yang lebih tepat tetapi saya benar-benar tidak mengerti bagaimana cara mengimplementasikannya.
LAdams87
7

Memiliki Con Posidielov mengatakan, rute saat hadir dalam this.props.location.pathname.

Tetapi jika Anda ingin mencocokkan bidang yang lebih spesifik seperti kunci (atau nama), Anda dapat menggunakan matchPath untuk menemukan referensi rute asli.

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
sumber
0

Menambahkan

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

Kemudian ubah ekspor komponen Anda

export default withRouter(ComponentName)

Kemudian Anda dapat mengakses rute langsung di dalam komponen itu sendiri (tanpa menyentuh apa pun di proyek Anda) menggunakan:

window.location.pathname

Diuji Maret 2020 dengan: "versi": "5.1.2"

Siobhan
sumber
Tidak yakin tentang yang ini. Tentu, ini memberikan nama path saat ini, tetapi itu tidak berubah jika saya menavigasi ke halaman baru.
alex