2017-03-23 9 views
2

Ich versuche, den aktuellen Pfad des Reagieren-Routers in einem Container zu erhalten, damit ich es an eine untergeordnete Komponente weitergeben kann, die den Sichtbarkeitsfilter ändert.Erhalten Reagieren Router-Pfad in Requisiten mit Redux OwnProps

Genauer gesagt, ich versuche, ein Navigationsmenü markieren Sie die derzeit aktive Seite.

Ich verwende react, redux, react-router und react-router-redux, damit ich vom Redux-Speicher auf den Router-Status zugreifen kann.

Aus der Dokumentation für react-router-redux, sagt es so etwas wie dies zu tun:

function mapStateToProps(state, ownProps) { 
    return { 
    id: ownProps.params.id, 
    filter: ownProps.location.query.filter 
    }; 
} 

Hier ist meine Container-Komponente:

import React, { Component, PropTypes } from 'react' 
import { connect } from 'react-redux' 
import { Link } from 'react-router' 
import { 
    Segment as UISegment, 
} from 'semantic-ui-react' 
import NavMenu from '../components/NavMenu' 

class MenuBar extends Component { 
    static propTypes = { 
    path: PropTypes.string.isRequired 
    } 

    render() { 
    const { path, } = this.props 

    return (
     <UISegment> 
     <NavMenu activePath={path} /> 
     </UISegment> 
    ) 
    } 
} 

const mapStateToProps = (state, ownProps) => { 
    return { 
    path: ownProps.route ? ownProps.route.path : "/" 
    } 
} 

export default connect(mapStateToProps)(MenuBar) 

Innerhalb der NavMenu Komponente, eine Menükomponente semantisch-UI Vergleichen Sie activePath mit einem eigenen Pfad und markieren Sie die aktive Schaltfläche.

Alles scheint in der Theorie zu funktionieren; Wenn ich auf die verschiedenen Teile des Menüs klicke, wird eine @@router/LOCATION_CHANGE Aktion ausgegeben. In den Redux-Dev-Tools sehe ich, dass sich der Zustand ändert. mapStateToProps wird jedoch nie aufgerufen, und diese Komponente wird nie erneut gerendert.

Irgendwelche Ideen? Ich dachte über die Verwendung der reaktiven Methoden wie shouldComponentUpdate nach, aber es scheint, dass react nicht einmal merkt, dass sich der Zustand oder die Requisiten ändern.

+0

Um einen Zustand in Redux zu ändern, müssen Sie es durch den Versand tun. –

Antwort

1

Das erste, was Sie beachten sollten, ist, dass Sie vom Router aus nicht auf den Router-Status zugreifen. Wenn Sie sich die react-router-redux docs anschauen, warnt Sie davor davor.

Sie sollten den Standort nicht direkt aus dem Redux Store lesen. Dies liegt daran, dass React Router asynchron arbeitet (um beispielsweise dynamisch geladene Komponenten zu verarbeiten) und Ihre Komponentenstruktur möglicherweise noch nicht synchron mit Ihrem Redux-Status aktualisiert wurde. Sie sollten sich auf die Props verlassen, die von React Router übergeben werden, da sie nur aktualisiert werden, nachdem der gesamte asynchrone Code verarbeitet wurde.

Ihr Behälter liest Daten aus ownProps, das nur die Requisiten, die in diese Container-Komponente übergeben werden. Das Beispiel in der react-router-redux-Dokumentation, auf die Sie verweisen, funktioniert nur für eine Routenkomponente der obersten Ebene (eine Komponente, die als Komponentenrequisite an eine React Router Route-Komponente übergeben wird). React Router übergibt die Router-Daten an alle Routen-Komponenten.

In Ihrem Fall ist MenuBar ein Kind dessen, was auch immer Ihre Top-Level-Komponente ist. Ihre zwei Optionen sind:

  1. Übergeben Sie die gewünschten Daten aus der Routenkomponente in die Menüleiste.
  2. Verwenden Routers withRouter höherer Ordnung Komponente reagieren, um die Werte in MenuBar https://github.com/ReactTraining/react-router/blob/v3/docs/API.md#withroutercomponent-options

auch zu injizieren, ich glaube, dass der Wert, den Sie suchen ownProps.location.pathname ist eher als ownProps.route.

Pfad

Einige Code für Option 1, da ich MenuBar gehe davon ist nicht zu tief in Ihrem Komponentenbaum verschachtelt:

Wenn Sie Ihre Route Config ist

<Router history={browserHistory}> 
    <Route path="/" component={AppLayout}> 
    <Route path="about" component={About}/> 
    <Route path="users" component={Users}/> 
    <Route path="*" component={NoMatch}/> 
    </Route> 
</Router> 

Ihre AppLayout wäre so etwas wie

const AppLayout = ({ children, location }) => { 
    return (
    <div> 
     <MenuBar path={ location.pathname } /> 
     { children } 
    </div> 
) 
} 

und MenuBar würde die Daten erhalten, die Sie suchen.

Verwandte Themen