462 words
2 minutes
Redirect client back to previous page after authentication

You can view these tutorials to set up Redux in order to do this example

Code#

After setting up redux in your application you want to create a callback action.

Actions#

export const setCallbackLink = callbackLink => ({ type: 'SET_CALLBACK_LINK', callbackLink });

createStore#

import { createStore as reduxCreateStore } from 'redux';

const reducer = (state, action) => {

  if (action.type === 'SET_CALLBACK_LINK') {
    return Object.assign({}, state, { callbackLink: action.callbackLink });
  }

  return state;
};

const initialState = {
  callbackLink: '/',
};

const createStore = () => reduxCreateStore(reducer, initialState)

export default createStore;

Login Component#

Our login component changes a little now. I have my component setup as a separate component that handles all the login task. If you have yours setup differently, all you need to do is wrap it around a Redux Connect and import your actions. When a user clicks on the button, we will store the current browser location into our redux store. I am using Gatsby in this example and pass the location as a props to my login button

import React, { Component } from 'react';
import { Login } from 'auth/Auth';
import { connect } from 'react-redux';
import { setCallbackLink } from '../actions';

const mapStateToProps = ({ callbackLink }) => ({ callbackLink });

const mapDispatchToProps = dispatch => ({
  setCallbackLink: callbackLink => dispatch(setCallbackLink(callbackLink)),
});

class LoginButton extends Component {
  constructor(props) {
    super(props);
    this.login = this.login.bind(this);
  }

  componentDidMount() {
    const { setCallbackLink: setLink, pathname } = this.props;
    setLink(pathname);
  }

  login() {
    Login();
    const { setAuthentication } = this.props;
    setAuthentication();
  }

  render() {
    return (
        <button onClick={this.login}>
        Log In
        </button>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(LoginButton);

Callback#

Our callback method also uses a similar convention that the login button uses. We just need to wrap our component with a Redux Connect. After that we grab the stored location from our Redux store. In my application, the index page just serves as a login, due to that I redirect the user to the search page instead of back to the index page. You can forgo that if/else statement.

import React, { Component } from 'react';
import loading from 'assets/images/loading.svg';
import { navigate } from 'gatsby';
import { handleAuthentication } from 'auth/Auth';
import { connect } from 'react-redux';
import { setCallbackLink } from '../actions';

const mapStateToProps = ({ callbackLink }) => ({ callbackLink });

const mapDispatchToProps = dispatch => ({
  setCallbackLink: callbackLink => dispatch(setCallbackLink(callbackLink)),
});

class Callback extends Component {
  componentDidMount() {
    const { callbackLink } = this.props;
    handleAuthentication();
    setTimeout(() => {
      if (callbackLink === '/') {
        navigate('/search');
      } else {
        navigate(callbackLink);
      }
    }, 1500);
  }

  render() {
    return (
      <div style={{
        position: 'absolute',
        display: 'flex',
        justifyContent: 'center',
        height: '98vh',
        width: '98vw',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        backgroundColor: 'white',
      }}
      >
        <img src={loading} alt="loading" />
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Callback);
Redirect client back to previous page after authentication
https://edwardbeazer.com/posts/redirect-client-back-to-previous-page-after-authentication/
Author
Edward Beazer
Published at
2018-11-02