2016-02-20 15 views
11

Ich habe mit diesem (reagieren-Router 2.0) browserHistory auf einem Router einzurichten:browserHistory.push nicht navigieren nicht auf neue Seite

import { browserHistory } from 'react-router' 

function requireAuth(nextState, replace) { 
    if (!services.auth.loggedIn()) { 
     replace({ 
      pathname: '/login', 
      state: { nextPathname: nextState.location.pathname } 
     }) 
    } 
} 

export default (store) => (
    <Router history={browserHistory}> 
    <Route path='/' component={AppLayout}> 
     <Route path="login" component={LoginContainer} /> 
     <Route path="map" component={MapContainer} onEnter={requireAuth} /> 
    </Route> 
    </Router> 
); 

ich dann in reagieren-Router zu verwenden browserHistory versuchen programmatisch Weg zu einer neuen Seite aus einer Sicht, ala:

import { browserHistory } from 'react-router' 

... 

browserHistory.push('/map'); 

Dies ändert die URL/Karte aber macht die Komponenten nicht in dieser Strecke. Was mache ich falsch?

+0

Kann ich Ihren 'requireAuth'-Handler sehen, auch die Kartenansicht? –

+0

ok - hinzugefügt. Hinweis: Das Gleiche passiert (/ map wird nicht gerendert), wenn ich das onEnter-Attribut nicht habe. – outside2344

+0

ja - die browserHistory.push ('/ map') wird aufgerufen - und ich sehe die URL ändern, aber die neue Route-Komponente (MapContainer) wird nicht gerendert. Schließlich, aus Vollständigkeit, wenn ich auth ausschalte und direkt zu/map gehe, wird es richtig gerendert. – outside2344

Antwort

9

Wie in meinem Kommentar erwähnt hatte ich das gleiche Problem, aber ich habe einen Weg gefunden, es zum Laufen zu bringen.

In diesem Fall ändert sich Ihre Route, aber Ihre AppLayout-Komponente aktualisiert ihren Status nicht automatisch. Der Router scheint nicht automatisch eine Statusänderung der Komponente zu erzwingen. Im Grunde wird this.state.children auf Ihrem AppLayout nicht mit den neuen Kindern aktualisiert.

Die Lösung, die ich gefunden habe (und, vollständige Offenlegung, ich weiß nicht, ob das ist, wie Sie dies erreichen sollen, oder wenn es Best Practice ist) ist die componentWillReceiveProps Funktion zu verwenden und this.state.children mit den Kindern zu aktualisieren von den neuen Stützen:

componentWillReceiveProps(nextProps) { 
    this.setState({ 
     children: nextProps.children 
    }); 
} 

Hoffnung hilft dieses!

+2

Dies scheint der beste Weg zu sein, aber dies ist die einzige Antwort, die ich im Internet für dieses Problem finden kann, verbunden mit einer wirklich mittelmäßigen Dokumentation über GitHub. Könnten Sie das bitte so weit wie möglich erläutern? Ich bin mir nicht sicher, wo genau ich componentWillReceiveProps verwenden soll, in meinem Top-Level-Komponentencontainer meinen Router? Ich verwende var Kinder = React.Children.map (Kinder, Funktion (Kind) { return React.cloneElement (Kind, { Benutzer: Benutzer, Schlüssel: Schlüssel }); }); klonen meine Requisiten, innerhalb einer reinen js-Funktion. – mibbit

2

Eine alternative Lösung, die es dem Router ermöglicht, zu einem anderen Abschnitt Ihrer App zu navigieren, ohne eine Aktualisierung über die Lebenszyklusmethode erzwingen zu müssen, verwendet den Context-Router. Alles, was Sie brauchen, ist eine context in Ihrer Komponente zu erklären (Router Instanziierung und anderen Code der Kürze halber weggelassen):

class MyComp extends Component { 
    static contextTypes = { 
    router: PropTypes.object 
    } 

    handleClick =() => { 
    this.context.router.push('/other/route') 
    } 
} 

Für Ursache (n) ich bin mir nicht bewusst, browserHistory.push() für nicht funktioniert ich, wenn auch browserHistory.goBack() und .goForward() tat.

Verwandte Themen