I want to define a URL that could be used to logout the user (dispatch an action that would logout the user). I have not found examples showing how to implement a route dispatching an event.
How to handle logout route in Redux?
Asked Answered
Define a route /authentication/logout
:
import React from 'react';
import {
Route,
IndexRoute
} from 'react-router';
import {
HomeView,
LoginView,
LogoutView
} from './../views';
export default <Route path='/'>
<IndexRoute component={HomeView} />
<Route path='/authentication/logout'component={LogoutView} />
<Route path='/authentication/login' component={LoginView} />
</Route>;
Create a LogoutView
that dispatches an action upon componentWillMount
:
import React from 'react';
import {
authenticationActionCreator
} from './../actionCreators';
import {
connect
} from 'react-redux';
import {
pushPath
} from 'redux-simple-router';
let LogoutView;
LogoutView = class extends React.Component {
componentWillMount () {
this.props.dispatch(authenticationActionCreator.logout());
this.props.dispatch(pushPath('/'));
}
render () {
return null;
}
};
export default connect()(LogoutView);
The componentWillMount
callback dispatches two actions:
- To destroy user session.
- To redirect user to the
IndexRoute
.
this.props.dispatch(authenticationActionCreator.logout());
this.props.dispatch(pushPath('/'));
I am not 100% sure whether thats how the logout scenario should be handled. Please suggest an edit or add your answer if this is not a canonical approach. –
Shavers
It would be better to split
logout
and pushPath
actions. pushPath
should be in componentDidMount
–
Exuberate @Exuberate What is the reason for that? –
Shavers
To make things go right. Some components may also want to update and upon logout, but you are firing a route change immediately. It was only my personal point of view if you don't have issues here, that is okay to leave it as is. –
Exuberate
Thank you for clarification. –
Shavers
Probably should redirect after upon success ( if there is any server call ). We need some types of promise. –
Goner
Here is a more current implementation for such /logout
page:
import { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router'
import * as authActionCreators from '../actions/auth'
class LogoutPage extends Component {
componentWillMount() {
this.props.dispatch(authActionCreators.logout())
this.props.router.replace('/')
}
render() {
return null
}
}
LogoutPage.propTypes = {
dispatch: PropTypes.func.isRequired,
router: PropTypes.object.isRequired
}
export default withRouter(connect()(LogoutPage))
Can you explain what makes this a "more current" implementation? –
Shavers
agree - I would not say this is a more current implementation but an alternative implementation using
react-router
over redux-simple-router
.I assume this would fit most use cases using react-router
which is more commonly used and includes the 'withRouter' functionality which was recently introduced, so why the comment. :-) –
Calenture First, please note that this implementation will work both with or without redux-simple-router (which, by the way, was renamed to react-router-redux a while ago). You can use Redux-style actions if you like, but it's not needed and IMHO it's not strictly related to the original routing problem. This implementation also takes advantage of the recently introduced
withRouter
higher-order component to make it simpler :) –
Brahe withRouter should be around connect, not the other way around (to prevent screen refresh problems) –
Poised
@Poised could you please elaborate? –
Brahe
Sure, react-router uses global context to navigate, this means that a navigation event doesn't impact
props
and therefore, a pure component wouldn't know it has to re-render. This means that you can navigate and "nothing happens". In order to prevent this, you can use withRouter, which supplies the location prop. This prop changes in case of a navigation event, the child React component will therefore re-render. That is why it has to be around the connect call, and not the other way around. –
Poised Here is the most current implementation for /logout
page:
import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
import * as authActionCreators from "../actions/auth";
class LogoutPage extends Component {
static propTypes = {
dispatch: PropTypes.func.isRequired
};
componentWillMount() {
this.props.dispatch(authActionCreators.logout());
}
render() {
return (
<Redirect to="/" />
);
}
}
export default connect()(LogoutPage);
Works for:
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"prop-types": "^15.5.10",
© 2022 - 2024 — McMap. All rights reserved.
/api/logout
page or something like this, that does actual logout on the backend – Exuberatewindow.localStorage
). Thats a standard JSON Web Token authentication implementation. Backend is not aware of user session. REST, by definition, is stateless (en.wikipedia.org/wiki/Representational_state_transfer#Stateless). – Shavers