React-Router erhält this.props.location in untergeordneten Komponenten

79

Soweit ich weiß <Route path="/" component={App} />, gibt Will AppRouting-bezogene Requisiten wie locationund params. Wenn meine AppKomponente viele verschachtelte untergeordnete Komponenten enthält, wie kann ich der untergeordneten Komponente Zugriff auf diese Requisiten gewähren, ohne:

  • Requisiten aus App übergeben
  • mit Fensterobjekt
  • Erstellen von Routen für verschachtelte untergeordnete Komponenten

Ich dachte, ich this.context.routerhätte einige Informationen zu den Routen, aber es this.context.routerscheint nur einige Funktionen zu geben, um die Routen zu manipulieren.

xiaofan2406
quelle
In der App-Komponente finden Sie die direkt verschachtelte untergeordnete Komponente unter this.props.children
gu mingfeng

Antworten:

135

(Update) V5.1 & Hooks (erfordert Reaktion> = 16.8)

Sie können verwendet werden useHistory, useLocationund useRouteMatchin der Komponente zu erhalten match, historyund location.

const Child = () => {
  const location = useLocation();
  const history = useHistory();
  const match = useRouteMatch("write-the-url-you-want-to-match-here");

  return (
    <div>{location.pathname}</div>
  )
}

export default Child

(Update) V4 & V5

Sie können mit withRouterHOC einzuspritzen , um match, historyund locationin Ihrer Komponente Requisiten.

class Child extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  }

  render() {
    const { match, location, history } = this.props

    return (
      <div>{location.pathname}</div>
    )
  }
}

export default withRouter(Child)

(Update) V3

Sie können mit withRouterHOC einzuspritzen , um router, params, location, routesin der Komponente Requisiten.

class Child extends React.Component {

  render() {
    const { router, params, location, routes } = this.props

    return (
      <div>{location.pathname}</div>
    )
  }
}

export default withRouter(Child)

Ursprüngliche Antwort

Wenn Sie die Requisiten nicht verwenden möchten, können Sie den Kontext wie in der Dokumentation zu React Router beschrieben verwenden

Zuerst müssen Sie Ihr childContextTypesund einrichtengetChildContext

class App extends React.Component{

  getChildContext() {
    return {
      location: this.props.location
    }
  }

  render() {
    return <Child/>;
  }
}

App.childContextTypes = {
    location: React.PropTypes.object
}

In diesem Kontext können Sie dann auf das Standortobjekt in Ihren untergeordneten Komponenten zugreifen

class Child extends React.Component{

   render() {
     return (
       <div>{this.context.location.pathname}</div>
     )
   }

}

Child.contextTypes = {
    location: React.PropTypes.object
 }
QoP
quelle
Danke für den Zeiger. Ich habe diesen Teil der Dokumentation nicht gelesen. Ich dachte, es gibt nurcontext.router
xiaofan2406
3
Ich bin neu in React. Verzeihen Sie mir also, wenn ich falsch liege, aber was ist falsch daran window.location.pathname?
Artur Barseghyan
1
window.location ist veränderbar, daher wird es als bewährte Methode angesehen, nicht darauf zuzugreifen, und es wird bevorzugt, eine unveränderliche Version zu verwenden. Ich denke auch, dass es möglich ist, logische Speicherorte zu verwenden, die sich vom window.location unterscheiden (zumindest trifft dies in nextjs zu), so dass es möglich ist, einen anderen Speicherort von Ihrem Router zu erhalten als den direkten Fensterverlauf
Chanoch
@ArturBarseghyan Das windowObjekt existiert nicht, wenn der React-Code auf dem Server ausgeführt wird, z. B. um serverseitiges Routing zu implementieren.
ChrisW
4

Wenn die oben genannte Lösung bei Ihnen nicht funktioniert hat, können Sie sie verwenden import { withRouter } from 'react-router-dom';


Mit dieser Option können Sie Ihre untergeordnete Klasse exportieren als -

class MyApp extends Component{
    // your code
}

export default withRouter(MyApp);

Und deine Klasse mit Router -

// your code
<Router>
      ...
      <Route path="/myapp" component={MyApp} />
      // or if you are sending additional fields
      <Route path="/myapp" component={() =><MyApp process={...} />} />
<Router>
skWyz
quelle