2015-11-19 19 views
21

Chcę skonfigurować React Router w następujący sposób. W przypadku dopasowania określonej trasy użytkownik zostaje przekierowany na inny. Documentation stwierdza, że ​​jest to możliwe, ale nie zapewnia dokładnej metody osiągnięcia tego. Czy ktoś ma wgląd w to?Jak korzystać z funkcji przekierowania routera?

type EnterHook = (nextState: RouterState, replaceState: RedirectFunction, callback?: Function) => any; 

type RedirectFunction = (state: ?LocationState, pathname: Pathname | Path, query: ?Query) => void; 

Odpowiedz

36

EDITZobacz inne odpowiedzi na nowe, nie reagują-Router nieaktualnych składni


Jest to dobry przykład jak używać haka onEnter w auth-flow example. Oto odpowiedni kod:

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

render((
    <Router history={history}> 
    <Route path="/" component={App}> 
     <Route path="login" component={Login} /> 
     <Route path="logout" component={Logout} /> 
     <Route path="about" component={About} /> 
     <Route path="dashboard" component={Dashboard} onEnter={requireAuth} /> 
    </Route> 
    </Router> 
), document.getElementById('example')) 

Jak widać, gdy trasa jest dostępna /dashboard funkcję requireAuth jest tzw. Otrzymuje dwa argumenty: nextState, który jest obiektem RouterState reprezentującym stan, który użytkownik ma zamiar wprowadzić, oraz replaceState, RedirectFunction, który można wywołać w celu zastąpienia tego stanu czymś innym. W tym przypadku, jeśli użytkownik nie jest zalogowany, requireAuth połączeń replaceState tak:

replaceState({ nextPathname: nextState.location.pathname }, '/login') 

Drugi argument jest oczywiście ścieżka użytkownik zostanie przekierowany. Pierwszym argumentem jest obiekt, który może zawierać dowolne dane, które chcemy mieć dla obsługi trasy (w tym przypadku komponentu Login). Tutaj ścieżka, do której użytkownik próbował przejść (/dashboard) jest ustawiona jako właściwość nextPathname, więc po zalogowaniu użytkownik może zostać przekierowany na tę stronę (patrz metoda handleSubmit w komponencie Login).

Jeśli użytkownik jest zalogowany, to requireAuth nic nie robi, a ponieważ replaceState nigdy nie jest wywoływana, trasa działa tak jak zwykle, co oznacza, że ​​komponent jest renderowany jako Dashboard.

+0

Dzięki tej dokładnej odpowiedzi! – Jason

+0

Używam renderowania uniwersalnego i niestety ta metoda powoduje przekierowania 302. Czy istnieje sposób, w jaki mógłbym użyć przekierowań 301 w przypadku żądania serwera? –

16

Głosowanie do każdego, kto czyta to pytanie od wersji routera reakcji 2.0.0, replaceState (stan, ścieżka, zapytanie), jest teraz przestarzałe. Musisz teraz użyć replace (location) z deskryptorem lokalizacji.

https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md#link-to-onenter-and-isactive-use-location-descriptors

Z ich przewodnikiem:

// v1.0.x 
(nextState, replaceState) => replaceState(null, '/foo') 
(nextState, replaceState) => replaceState(null, '/foo', { the: 'query' }) 

// v2.0.0 
(nextState, replace) => replace('/foo') 
(nextState, replace) => replace({ pathname: '/foo', query: { the: 'query' } }) 
+0

Witam.Kiedy używamy funkcji zamiany, nie zachowuje ona stanu sklepu podczas przekierowania. Jak mogę to zrobić? Chodzi mi o to, jak przekazać stan sklepu (wraz z dyspozytorami akcji) na następnej trasie. – myDoggyWritesCode

+1

Hi @ user3241111 Dodałem poniżej odpowiedź, która, mam nadzieję, pomaga wyjaśnić. – justswim

10

Oto przykład jak to zrobić z react-router 2.0.0 (używając replace zamiast replaceState):

W routera. jsx:

function requireAuth(nextState, replace) { 
    if (!userExists()) { 
    replace({ 
     pathname: '/signin', 
     state: { nextPathname: nextState.location.pathname } 
    }) 
    } 
} 

export const renderRoutes =() => (
    <Router history={browserHistory}> 
     <Route path="protectedRoute" component={Protected} onEnter={requireAuth} /> 
     <Route path="signin" component={SignIn} /> 
    </Route> 
    </Router> 
); 

Następnie wewnątrz SignIn składnika, można przekierować po pomyślnym znakiem w ten sposób:

import { browserHistory } from 'react-router'; 

signInFunction({params}, (err, res) => { 
    // Now in the sign in callback 
    if (err) 
    alert("Please try again") 
    else { 
    const location = this.props.location 
    if (location.state && location.state.nextPathname) { 
     browserHistory.push(location.state.nextPathname) 
    } else { 
     browserHistory.push('/') 
    } 
    } 
}) 
+0

Dzięki za odpowiedź. Są 2 rzeczy różne od twojego przykładu powyżej i mojego scenariusza. 1. to moje uwierzytelnienie TOKEN oparte, a NIE jak przekierowanie go do znaku w formularzu, który jest trasą (nie w moim przypadku) w tej samej aplikacji. Drugi przypadek .. W momencie, w którym robisz zamień (pathname: '/ signin' ....) Już wiem, czy mój użytkownik jest zalogowany, warunek "if (userExists())" jest ZAWSZE PRAWDA, ponieważ jest z pewnością zalogowałem się. Chcę tylko zastąpić stronę "/ notFound", ale stan aplikacji gubi się podczas ładowania tej trasy. Chcę chronić niektóre komponenty przed zalogowanymi użytkownikami. – myDoggyWritesCode

+0

Moja aplikacja jest izomorficzna, więc pojawia się problem. Wysyłam mój TOKEN w celu uwierzytelnienia do innego adresu URL wraz z "zwrotnym adresem URL", który uwierzytelnił TOKENA i wysyła przekierowania z powrotem do "adresu URL powrotu". więc jeśli robię "cb()", przekierowuje do chronionego adresu URL, a także zachowuje moje UserDetails, ale jeśli użyłem "replace ("/notFound ")", to zapomina stanu .. Na instancji, gdzie mam do cb() lub zamień (..), stan serwera ma już userDetails, które chcę przekazać do trasy 'notFound'. – myDoggyWritesCode

+0

Dzięki @justswim To rozwiązało moją pętlę infinit – mike00

Powiązane problemy