New to this.
I have a React-Redux app where I have loaded a JWT token and as a result the app indicates this with an Authorized setting = to "true" in state. That works and it now knows its authorised.
On the Navbar I have a "Log Out" option that I want to click and accordingly removes the JWT from local storage and re-renders the navbar to display "Login".
First of all here is the Navbar with the test for Authorize etc:
import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from "react-bootstrap"
import { LinkContainer } from 'react-router-bootstrap'
class NavMenu extends Component {
render() {
const { isAuthorised, username } = this.props;
return (
<div className='main-nav'>
<Navbar inverse collapseOnSelect>
<Navbar.Header>
<Navbar.Brand>
<Link to={'/'}>JobsLedger</Link>
</Navbar.Brand>
{<Navbar.Toggle />}
</Navbar.Header>
<Navbar.Collapse>
<Nav>
<LinkContainer to={'/'}>
<NavItem eventKey={1}><span className='glyphicon glyphicon-home'></span> Home</NavItem>
</LinkContainer>
<LinkContainer to={'/counter'}>
<NavItem eventKey={2} ><span className='glyphicon glyphicon-education'></span> Counter</NavItem>
</LinkContainer>
<LinkContainer to={'/fetchdata'}>
<NavItem eventKey={3}><span className='glyphicon glyphicon-th-list'></span> Fetch data</NavItem>
</LinkContainer>
{isAuthorised && (
<NavDropdown eventKey={4} title="Clients" id="basic-nav-dropdown">
<LinkContainer to={'/clients/index'}>
<MenuItem eventKey={4.1}><span className='glyphicon glyphicon-th-list'></span> Client List</MenuItem>
</LinkContainer>
<LinkContainer to={'/clients/create'}>
<MenuItem eventKey={4.2}><span className='glyphicon glyphicon-user'></span> New Client</MenuItem>
</LinkContainer>
<MenuItem eventKey={4.3}>Something else here</MenuItem>
<MenuItem divider />
<MenuItem eventKey={4.4}>Separated link</MenuItem>
</NavDropdown>
)}
</Nav>
{isAuthorised ? (
<Nav pullRight>
<NavItem eventKey={5}><span className='glyphicon glyphicon-user'></span> Hello {username}</NavItem>
<LinkContainer to={'/logOut'}>
<NavItem eventKey={6}> Log Out</NavItem>
</LinkContainer>
</Nav>
) : (
<Nav pullRight>
<LinkContainer to={'/login'}>
<NavItem eventKey={7} ><span className='glyphicon glyphicon-user'></span> Login</NavItem>
</LinkContainer>
</Nav>
)}
</Navbar.Collapse>
</Navbar>
</div>
);
}
}
const mapStateToProps = (state) => ({
isAuthorised: state.login.isAuthorised,
username: state.login.username,
})
export default connect(mapStateToProps)(NavMenu);
Note that I have simply included an "isAuthorized" ternary to display different links if Authorized. Upon clicking "Logout" It should recheck that ternary and update...
The other parts of logout
I have a function called "clearJWT" in another file that is imported into the reducer file.
export const clearJwt = () => {
localStorage.removeItem(TOKEN_KEY)
}
The thing is there is no "event" that I can hang an action off being that it should just render "Logged Out..." and remove the JWT from local storage using the function above.
I have, for the moment combined the actions and the reducer but will separate a little later.
So I have three files then. The reducer with the actions at the top. The Logout container => "logoutContainer" and Logout which is a really simple one liner.
Here is the code I set up.
The action in the reducer file (called reducer.js):
export const logoutUser = () =>
(dispatch, getState) => {
clearJwt()
({ type: LOGOUT_USER })
}
The reducer option for LOGOUT_USER:
case LOGOUT_USER:
return {
...state,
isAuthorised: false,
}
and here is my logoutContainer:
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import Logout from './logout'
import { logoutUser } from './reducer'
class LogoutContainer extends Component {
static contextTypes = {
router: PropTypes.object.isRequired
}
componentWillMount() {
console.log('Logout - componentDidMount')
logoutUser()
}
render() {
return (
<Logout />
)
}
}
const mapStateToProps = (state) => ({
isAuthorised: state.login.isAuthorised,
})
const mapDispatchToProps = (dispatch) => ({
logoutUser: () => dispatch(logoutUser()),
})
export default connect( mapDispatchToProps)(LogoutContainer)
I thought I could just call the action on the componentWillMount() which would call "logoutUser()" which would update state while also rendering "Logged out.." and updating the menu bar.
I found this question which indicated I should use "componentDidMount()" however it didnt change anything and logout still isnt called...
I dont think this approach is correct.. (well it doesnt work so thats a clue)
How do I click on the "Log Out" link on the NavBar, go to "LogoutContainer", automatically call the action ( logoutUser() ) and re-render the page as well as have the Navbar recheck the state re "Authorised" and realise now that its not authorized and rerender the navbar also?
Is this the right way to do it even?
In mycase "logoutUser()" isnt even called..