Tuomas Toivonen
Tuomas Toivonen

Reputation: 23492

react separate routes for logged in and guest user

React-router-component's official github page mentions as follows:

For example you can return a different set of allowed locations for anonymous and signed-in users.

That's exactly what I want to achieve, but I can't actually find the tutorial anywhere how to do this.

So basically I want to have separate routers for logged in user and guest user. Guest router defaults to login page and may redirect to login error page or about page. When user have successfully logged in, logged in router takes control and defaults to system overview page. Logged in routes should also render navigation panel to every page.

Upvotes: 1

Views: 5374

Answers (2)

Pransh Tiwari
Pransh Tiwari

Reputation: 4182

After user login/signup you can change the state(eg this.setState({isLoggedIn: true}) in your parent component( index.js or App.js ). Now based upon the state you can redirect the user to the desired location.

<Route path='/dashboard' 
       render={() => 
          this.state.isLoggedIn ? 
             <Dashboard user={this.state.user} /> : 
             <Redirect to="/home"/> 
       }
/>

You can see the entire code here: link. Still if any doubts, ask in the comment section.

Upvotes: 1

Mjuice
Mjuice

Reputation: 1288

What you can do is wrap your routes in what is called a composed component. It will check to see if your user is authenticated, if he/she is not, it will kick them back to whichever route you choose.

Here is an examples of a composed component, then I will show you how to use it in your routes file.

import React, {Component} from 'react';
import {connect} from 'react-redux';

export default function(ComposedComponent) { //This code right here serves as the base for any high order component 

    class Authentication extends Component {

        static contextTypes = { //static creates a class level object that will give any other method in this component access to Authentication.contextTypes
            router: React.PropTypes.object //This lets react know ahead of time we will use the router and it defines its type as object
        }

        componentWillMount() {
            if (!this.props.authenticated) {
                this.context.router.push('/signup');
            }

        }

        componentWillUpdate(nextProps) {
         //this lifecycle method runs when the component is about to update with new props, nextProps are those new properties for the rerender
            if (!nextProps.authenticated) {
                this.context.router.push('/signup');
            }
        }

        //{...this.props} makes sure the new combined component Enhanced Component will have all the props of the original component passed into this function/Authentication class
        //it maintains those props even though it's combining two components together to form a Enhanced Component
        render() {

            return (
                <ComposedComponent {...this.props} />
            );
        }

    }

    function mapStateToProps(state) {
        return { authenticated: state.user.authenticated };
    }

    return connect(mapStateToProps)(Authentication);
}

I've imported the Authentication component above as RequireAuth in my routes file. It will check to see if a user is authenticated in my redux state. If the user is not authenticated, the user is kicked back to my '/signup' route. You cans see where that happens in the lifecycle methods of Authentication. Basically if I wrap any component in my routes with RequireAuth, those components will inherit its lifecycle methods. You can use it for more than just checking to see if they are logged in or not. You can have certain users with admin access etc. You just need to check the user's qualifications in the life cycle methods and push the route wherever you want.

export default (
    <Route path="/" component={App}>
        <IndexRoute component={Home} />
        <Route path="inventory" component={RequireAuth(Inventory)} />
        <Route path="signup" component={Signup} />
        <Route path="single-product/:id" component={RequireAuth(Product)} />
        <Route path="examples" component={Examples} />
        <Route path="pricing" component={Pricing} />
        <Route path="profile" component={RequireAuth(Profile)} />
        <Route path="allProducts" component={RequireAuth(AllProducts)} />
        <Route path="reporting" component={RequireAuth(ReportingContainer)} />
        <Route path="signout" component={Signout} />

    </Route>
);

Upvotes: 0

Related Questions