2016-02-20 13 views
11

Wcześniej skonfigurować browserHistory na routerze z tym routerem (reagują-2.0):browserHistory.push nie przejść do nowej strony

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

ja potem próbuje użyć browserHistory w reagują-router programowo droga do nowej strony z myślą, ala:

import { browserHistory } from 'react-router' 

... 

browserHistory.push('/map'); 

To zmienia adres URL/mapy, ale nie czyni składników w tej trasie. Co ja robię źle?

+0

Czy mogę zobaczyć Twój program obsługi "requireAuth", także widok mapy? –

+0

ok - dodano. uwaga: to samo dzieje się (/ map nie jest renderowana), jeśli nie mam atrybutu onEnter. – outside2344

+0

yes - wywoływana jest browserHistory.push ("/ map") - widzę zmianę adresu URL, ale nowy komponent Route (MapContainer) nie jest renderowany. Wreszcie, dla kompletności, jeśli wyłączę auth i przejdź do/map bezpośrednio, to renderuje się poprawnie. – outside2344

Odpowiedz

9

Jak wspomniano w moim komentarzu miałem ten sam problem, ale znalazłem sposób, aby to działało.

To, co się dzieje, to Twoja Trasa się zmienia, ale Twój składnik AppLayout nie aktualizuje automatycznie stanu. Router nie wydaje się automatycznie wymuszać zmiany stanu komponentu. Zasadniczo, this.state.children na AppLayout nie jest aktualizowany z nowymi dziećmi.

Rozwiązanie, które znalazłem (i pełne ujawnienie, nie wiem, czy to jest jak jesteś ma to osiągnąć, lub jeśli jest to najlepsza praktyka) jest skorzystanie z funkcji componentWillReceiveProps i aktualizować this.state.children z dziećmi z nowych rekwizytów:

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

Mam nadzieję, że to pomoże!

+2

Wydaje się to najlepszym sposobem, ale jest to jedyna odpowiedź, jaką mogę znaleźć w Internecie na ten problem, w połączeniu z naprawdę mierną dokumentacją dotyczącą github. Czy mógłbyś rozwinąć to w jakikolwiek możliwy sposób? Nie jestem pewien, gdzie dokładnie powinienem używać componentWillReceiveProps, w moim kontenerze komponentu najwyższego poziomu mojego routera? Używam var = React.Children.map dzieci (dzieci, function (dziecko) { powrót React.cloneElement (child { użytkownik: użytkownik, klucz: klucz }); }); sklonować moje rekwizyty, w ramach czystej funkcji js. – mibbit

2

Alternatywne rozwiązanie, które umożliwia routerowi nawigację do innej sekcji aplikacji bez wymuszania aktualizacji przy użyciu metody cyklu życia, korzysta z routera kontekstowego. Wszystko czego potrzebujesz to zadeklarować contextType w swoim składnika (z pominięciem routera konkretyzacji i inny kod dla zwięzłość):

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

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

Ze względów (ów) nie jestem świadomy, browserHistory.push() nie działa dla ja, aczkolwiek browserHistory.goBack() i .goForward() zrobiły.

Powiązane problemy