React Router v4 - จะหาเส้นทางปัจจุบันได้อย่างไร


183

ฉันต้องการที่จะแสดง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 />?


คำตอบ:


77

ในรุ่น 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
โปรดทราบว่าสิ่งนี้สามารถใช้ได้ภายใน Router DOM เท่านั้น (เช่นคอมโพเนนต์ chid ไม่ใช่องค์ประกอบ class / functional ที่ใช้เราเตอร์) มันอาจจะชัดเจน แต่ไม่ใช่สำหรับมือใหม่อย่างฉัน :-) ฉันได้รับข้อผิดพลาดตลอดเวลา "useContext is undefined"
BennyHilarious

ยังนี้จะไม่ทำงานถ้าเราเตอร์redirectถูกนำมาใช้ สิ่งนี้จะอ่านเส้นทางก่อนการเปลี่ยนเส้นทาง
Sonic Soul

1
ขอบคุณสำหรับคำตอบนี้ ...
bellabelle

212

ในการตอบสนองเราเตอร์ 4 เส้นทางในปัจจุบันอยู่ใน this.props.location.pathname- เพิ่งได้รับ this.propsและยืนยัน หากคุณยังไม่เห็น แล้วคุณควรใช้มัณฑนากรlocation.pathnamewithRouter

อาจมีลักษณะเช่นนี้:

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คุณจำเป็นต้องใช้องค์ประกอบขั้นสูง (มักเรียกว่าเป็น withRouter"HOC")

ก่อนอื่นคุณจะต้องนำเข้าwithRouterดังนี้:

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

ถัดไปคุณจะต้องการที่จะใช้ withRouterคุณสามารถทำได้โดยเปลี่ยนการส่งออกส่วนประกอบของคุณ ก็จะให้คุณต้องการที่จะเปลี่ยนจากการexport default ComponentNameexport 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....เป็นเพียงแค่หูของเรา
KhoPhi

17

มีเบ็ดที่เรียกว่าuseLocationใน react-router v5 ไม่จำเป็นต้องใช้ 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 เพื่อเอาใจผู้ใช้บางคน อย่างไรก็ตามฉันเชื่อว่าวิธีที่ดีกว่าคือการใช้ render prop และสร้างส่วนประกอบ PropsRoute ง่ายๆที่ผ่านอุปกรณ์ประกอบฉากเหล่านั้น การทดสอบนี้ง่ายกว่าเพราะคุณไม่ได้ "เชื่อมต่อ" ส่วนประกอบเช่น withRouter มีส่วนประกอบที่ซ้อนกันมากมายห่อหุ้มด้วยเสื้อนอกและมันจะไม่สนุก ข้อดีอีกอย่างก็คือคุณสามารถใช้บัตรผ่านนี้ในอุปกรณ์ประกอบฉากใดก็ตามที่คุณต้องการไปยังเส้นทาง นี่คือตัวอย่างง่ายๆโดยใช้การแสดงผล prop (ตัวอย่างที่แน่นอนจากเว็บไซต์ของพวกเขาhttps://reacttraining.com/react-router/web/api/Route/render-func ) (src / components / เส้นทาง / 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;

การใช้งาน: (แจ้งให้ทราบเพื่อรับ params เส้นทาง (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

มีคอน Posidielovthis.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 ด้วย: "version": "5.1.2"


ไม่แน่ใจเกี่ยวกับอันนี้ แน่นอนมันให้ชื่อพา ธ ปัจจุบัน แต่นั่นไม่เปลี่ยนแปลงหากฉันนำทางไปยังหน้าใหม่
alex
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.