You did not specify how and when isLoggedIn , isEmailConfirmed , isProfileCreated will be installed, so I assumed that they would be somehow set in the reduction storage before rendering.
I think that the best tool for this task would be to use the built-in Route rendering, a similar workflow example in RR4 documents .
I made an example CRA application that does what you need.
If you change the property values ββin redux / index.js :
const INITIAL_STATE = { isLoggedIn: false, isEmailConfirmed: false, isProfileCreated: false, }
... the application will use it to display the appropriate view, no matter what URL you are trying to get. For example, if you set isEmailConfirmed = true and isProfileCreated = false , then the only path you will have access to is /create-profile (CreateProfile component). If the user has completed each step of the registration steps and isProfileCreated = true , he will have access to each route, except for those that are registered.
Enhanced Route named AuthorizedRoute :
import React from 'react' import { Redirect, Route } from 'react-router-dom' import { connect } from 'react-redux' const AuthorizedRoute = ({ component: Component, isProfileCreated, isEmailConfirmed, isLoggedIn, ...rest }) => ( <Route {...rest} render={props => { //-- if user is fully registered - grant him every route except registration steps. if (isProfileCreated) { if (['/', '/create-account', '/create-profile', '/confirm-email'].includes(props.location.pathname)) { return <Redirect to="/dashboard" /> } else { return <Component {...props} /> } } //-- user is not fully registered so he needs to be redirected to next step... if (isEmailConfirmed) { if (props.location.pathname === '/create-profile') { return <Component {...props} /> } else { return <Redirect to="/create-profile" /> } } if (isLoggedIn) { if (props.location.pathname === '/confirm-email') { return <Component {...props} /> } else { return <Redirect to="/confirm-email" /> } } //-- ... or allowed to use `Login` or `CreateAccount` page if (props.location.pathname === '/' || props.location.pathname === '/create-account') { return <Component {...props} /> } return <Redirect to="/" /> }} /> ) export default connect( (state) => ({ isProfileCreated: state.isProfileCreated, isEmailConfirmed: state.isEmailConfirmed, isLoggedIn: state.isLoggedIn, }), )(AuthorizedRoute)
And here are certain components that know this logic:
class App extends Component { render () { return ( <div> <nav> <Link to="/">login</Link> <Link to="/create-account">create account</Link> <Link to="/confirm-email">confirm email</Link> <Link to="/create-profile">create profile</Link> <Link to="/dashboard">dashboard</Link> </nav> <Switch> <AuthorizedRoute exact path="/" component={Login} /> <AuthorizedRoute path="/create-account" component={CreateAccount} /> <AuthorizedRoute path="/confirm-email" component={ConfirmEmail} /> <AuthorizedRoute path="/create-profile" component={CreateProfile} /> <AuthorizedRoute path="/dashboard" component={Dashboard} /> <Redirect to="/" /> </Switch> </div> ) } }
I think that the most difficult part is to correctly identify the user and what he is allowed or not to do. In addition, it is only a matter of identifying the route to which he is trying to access, and providing this route or redirecting.