Right now, my router looks like this:
<Router history={browserHistory}>
<Route component={Provider}>
<Route path="/" component={AppPage}>
<Route path="login" component={LoginPage}/>
<Route component={LoggedinPage}>
<Route path="onboarding" component={OnboardingPage}/>
<Route component={OnboardedPage}>
<IndexRoute component={HomePage}/>
<Route path="settings" component={SettingsPage}/>
</Route>
</Route>
</Route>
</Route>
</Router>
LoggedinPage
redirects to /login
if the user isn't logged in and OnboardedPage
redirects to /onboarding
if the user hasn't completed the onboarding flow (choosing username, etc). However, I think more of these conditional redirects may be needed in the future. What's the best way to handle these conditional redirects? Is it possible to have a single component that handles all the redirects?
<Route>
s accept an onEnter
hook that is called when the route matches. A hook would look something like this:
function requireAuth(nextState, replace) {
if (!loggedIn()) {
replace({ pathname: 'login' });
}
}
Then use it like so:
<Route path="/" component={AppPage}>
<Route path="home" component={HomePage} onEnter={requireAuth}/>
<Route path="login" component={LoginPage}/>
</Route>
A more composable example, that lets you combine multiple checks:
function checkAuth() {
if (!loggedIn()) {
return { pathname: 'login' };
}
}
function checkOnboarding() {
if (!completedOnboarding()) {
return { pathname: 'onboarding' };
}
}
function redirect(...checks) {
return function(nextState, replace) {
let result;
checks.some(check => {
result = check();
return !!result;
});
result && replace(result);
};
}
Then combine away!
<Route path="/" component={AppPage}>
<Route path="home" component={HomePage}
onEnter={redirect(checkAuth, checkOnboarding)}/>
<Route path="login" component={LoginPage}/>
<Route path="onboarding" component={OnboardingPage}
onEnter={redirect(checkAuth)}/>
</Route>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With