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);