How to use React Router's redirect function? How to use React Router's redirect function? reactjs reactjs

How to use React Router's redirect function?


EDIT See other answer for new, non-deprecated react-router syntax


There's a good example of how to use the onEnter hook in the auth-flow example. Here's the relevant code:

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

As you can see, when the /dashboard route is accessed the requireAuth function is called. It receives two arguments: nextState, which is a RouterState object that represents the state the user is about to enter, and replaceState, a RedirectFunction that can be called to replace that state with something else. In this case, if the user isn't logged in, requireAuth calls replaceState like this:

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

The second argument is obviously the pathname the user will be redirected to. The very first argument is an object that can contain any data we want the route handler (in this case the Login component) to have. Here the pathname the user was trying to go to (/dashboard) is set as the nextPathname property so after logging in the user can be redirected to that page (see the handleSubmit method in the Login component).

If the user is logged in, requireAuth does nothing, and since replaceState is never called the route works as usual, which is to say the Dashboard component is rendered.


Heads up to anyone reading this question as of react-router 2.0.0, replaceState(state, pathname, query) is now deprecated. You must now use replace(location) with a location descriptor instead.

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

From their guide:

// 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' } })


Here is an example of how to do this with react-router 2.0.0 (using replace instead of replaceState):

In router.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>);

Then, inside SignIn component, you can redirect after a successful sign in like this:

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('/')    }  }})