Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect user to intended url after login Reactjs

I am working on a web app using Reactjs for my front end. I prevented users from accessing some pages excepted they are logged in. My problem is how to allow users access their intended url instead of redirecting them back to the home page which I currently do.

My routes are

<Switch>
    <Route path="/desired-page" component={requireAuth(DesiredPage)} />
    <Route path="/new-page" component={requireAuth(NewPage)} />
</Switch>

My requireAuth.js is

export default function(ComposedComponent) {
  class Authenticate extends React.Component {
    componentDidMount() {
      if (!this.props.isAuthenticated) {
        this.props.addFlashMessage({
          type: 'error',
          text: 'You need to login to access this page'
        });
        this.context.router.history.push('/login');
      }
    }
    render() {
      return (
        <ComposedComponent {...this.props} />
      )
    }
  }

  Authenticate.propTypes = {
    isAuthenticated: PropTypes.bool.isRequired,
    addFlashMessage: PropTypes.func.isRequired
  }

  Authenticate.contextTypes = {
    router:PropTypes.object.isRequired
  }

  function mapStateToProps(state) {
    return {
      isAuthenticated: state.auth.isAuthenticated
    }
  }
  return connect(mapStateToProps, { addFlashMessage })(Authenticate);
}
like image 259
Dayvino Avatar asked Jun 20 '17 09:06

Dayvino


1 Answers

So ReactTraining Docs provide you a location prop which represent where the app is now, where you want it to go, or even where it was.

While navigation to a Login route you can mention a state as to from which route you are navigating to Login. You can do that with

  • Redirect to
  • history.push
  • history.replace

To dynamically route, you can pass it with history.push like

const location = {
  pathname: '/login'
  state: { from: 'Main' }
}

history.push(location)

In your case it will be

import {withRouter} from 'react-router';
export default function(ComposedComponent) {
  class Authenticate extends React.Component {
    componentDidMount() {
      if (!this.props.isAuthenticated) {
        this.props.addFlashMessage({
          type: 'error',
          text: 'You need to login to access this page'
        });
        const location = {
            pathname: '/login'
            state: { from: {pathname: '/Main'} }
        }
        this.props.history.push(location);
      }
    }
    render() {
      return (
        <ComposedComponent {...this.props} />
      )
    }
  }

  Authenticate.propTypes = {
    isAuthenticated: PropTypes.bool.isRequired,
    addFlashMessage: PropTypes.func.isRequired
  }

  Authenticate.contextTypes = {
    router:PropTypes.object.isRequired
  }

  function mapStateToProps(state) {
    return {
      isAuthenticated: state.auth.isAuthenticated
    }
  }
  return connect(mapStateToProps, { addFlashMessage })(withRouter(Authenticate));
}

Now while Re-directing back after login you can access this param with

var {from} = this.props.location.state || {from: {pathname: '/'}}
this.props.history.push(from) 

NOTE: When you want to make use of history object from prop make sure to wrap your component with withRouter HOC.

I hope this helps :)

like image 117
Shubham Khatri Avatar answered Nov 03 '22 18:11

Shubham Khatri