Check if Logged in - React Router App ES6 Check if Logged in - React Router App ES6 reactjs reactjs

Check if Logged in - React Router App ES6


Every route has an onEnter hook which is called before the route transition happens. Handle the onEnter hook with a custom requireAuth function.

<Route path="/search" component={Search} onEnter={requireAuth} />

A sample requireAuth is shown below. If the user is authenticated, transition via next(). Else replace the pathname with /login and transition via next(). The login is also passed the current pathname so that after login completes, the user is redirected to the path originally requested for.

function requireAuth(nextState, replace, next) {  if (!authenticated) {    replace({      pathname: "/login",      state: {nextPathname: nextState.location.pathname}    });  }  next();}


In v4 you just create a route component that checks if uses is authenticated and return the next components and of course next component can be other routes.

import React, { Component } from 'react';import PropTypes from 'prop-types';import { connect } from 'react-redux';import { bindActionCreators } from 'redux';import { Route, Redirect } from 'react-router-dom';import AuthMiddleware from 'modules/middlewares/AuthMiddleware';class PrivateRoute extends Component {  static propTypes = {    component: PropTypes.func.isRequired,    isAuthenticated: PropTypes.bool,    isLoggedIn: PropTypes.func.isRequired,    isError: PropTypes.bool.isRequired  };  static defaultProps = {    isAuthenticated: false  };  constructor(props) {    super(props);    if (!props.isAuthenticated) {      setTimeout(() => {        props.isLoggedIn();      }, 5);    }  }  componentWillMount() {    if (this.props.isAuthenticated) {      console.log('authenticated');    } else {      console.log('not authenticated');    }  }  componentWillUnmount() {}  render() {    const { isAuthenticated, component, isError, ...rest } = this.props;    if (isAuthenticated !== null) {      return (        <Route          {...rest}          render={props => (            isAuthenticated ? (              React.createElement(component, props)            ) : (              <Redirect                to={{                  pathname: isError ? '/login' : '/welcome',                  state: { from: props.location }                }}              />            )          )}        />      );    } return null;  }}const mapStateToProps = (state) => {  return {    isAuthenticated: state.auth.isAuthenticated,    isError: state.auth.isError  };};const mapDispatchToProps = (dispatch) => {  return bindActionCreators({    isLoggedIn: () => AuthMiddleware.isLoggedIn()  }, dispatch);};export default connect(mapStateToProps, mapDispatchToProps)(PrivateRoute);


This version of the onEnter callback finally worked for react-router (v2.8):

 requireAuth(nextState,               replace)   {      if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function)         replace('/login')   }

The link which explains react-router redirection differences between V1 vs v2 is here. Relevant section quoted below:

Likewise, redirecting from an onEnter hook now also uses a location descriptor.// 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' } })

Full Code Listing Below (react-router version 2.8.1):

requireAuth(nextState,               replace){   if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function)     replace('/login');}render() {  return (     <Router history={hashHistory}>        <Route path="/" component={AppMain}>           <Route path="login" component={Login}/>           <Route path="logout" component={Logout}/>           <Route path="subject" component={SubjectPanel} onEnter={this.requireAuth}/>           <Route path="all" component={NotesPanel} onEnter={this.requireAuth}/>        </Route>     </Router>  );}