新手。
我有一个React-Redux应用程序,我在其中加载了一个JWT令牌,因此应用程序用授权设置指示这个设置=" true"在州。这有效,现在知道它的授权。
在Navbar上我有一个" Log Out"我想要点击的选项,并相应地从本地存储中删除JWT并重新呈现导航栏以显示"登录"。
首先,这里是带有Authorize等测试的Navbar:
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);
请注意,我只是简单地包含了一个&#34; isAuthorized&#34;如果授权,三元显示不同的链接。点击&#34;退出&#34;它应该重新检查三元并更新......
退出的其他部分
我有一个名为&#34; clearJWT&#34;在另一个导入reducer文件的文件中。
export const clearJwt = () => {
localStorage.removeItem(TOKEN_KEY)
}
事情是没有&#34;事件&#34;我可以暂停一个动作,因为它应该只是渲染&#34;登出...&#34;并使用上述功能从本地存储中删除JWT。
我暂时将动作与减速器结合起来,但稍后会分开。
那么我有三个文件。减速器的动作在顶部。 Logout容器=&gt; &#34; logoutContainer&#34;和Logout这是一个非常简单的单线。
这是我设置的代码。
reducer文件中的操作(称为reducer.js):
export const logoutUser = () =>
(dispatch, getState) => {
clearJwt()
({ type: LOGOUT_USER })
}
LOGOUT_USER的reducer选项:
case LOGOUT_USER:
return {
...state,
isAuthorised: false,
}
这是我的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)
我以为我可以在componentWillMount()上调用action来调用&#34; logoutUser()&#34;这将更新状态,同时也渲染&#34;退出..&#34;并更新菜单栏。
我发现了this问题表明我应该使用&#34; componentDidMount()&#34;但它没有改变任何东西,退出仍然没有被称为......
我不认为这种方法是正确的..(它不起作用,所以这是一个线索)
如何点击&#34;退出&#34;在NavBar上链接,转到&#34; LogoutContainer&#34;,自动调用动作(logoutUser())并重新渲染页面,并让Navbar重新检查状态re&#34; Authorized&#34;现在意识到它还没有授权并重新退回导航栏?
这是否是正确的方法呢?
在mycase&#34; logoutUser()&#34;甚至没有被称为..
答案 0 :(得分:2)
我需要将此作为答案发布,因为它需要注释,但首先将其视为建议和一些代码清理。你必须自己测试一下。
首先你的行动。这是编写动作的“thunk动作”处理程序方式。你可以看到它是一个函数返回另一个函数(因此thunk)。在你的代码中你实际上从来没有调用它(这就是为什么没有被调用,它停在thunk。如果你想使用redux-thunk中间件读取如何使用它,它有点不同于“正常”调度。Redux-thunk docs.
其次你没有调用调度员,所以你的动作不会被调用,而redux不会重新渲染你的应用程序。
export const logoutUser = () =>
(dispatch, getState) => {
clearJwt()
dispatch({ type: LOGOUT_USER }) //Call the dispatcher with your action
}
在您的容器中,您需要在评论中正确使用@ si2030中提到的thunk和操作。
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import Logout from './logout'
import { logoutUser } from './reducer'
class LogoutContainer extends Component {
componentDidMount() {
this.props.logoutUser();
}
render() {
return (
<Logout />
)
}
}
const mapStateToProps = (state) => ({
isAuthorised: state.login.isAuthorised,
});
//Just return a map with your actions and call them with this.props.yourAction
const mapDispatchToProps = {
logoutUser
};
};
//Connect is a function that takes your state map and your actions map.
export default connect(mapStateToProps,mapDispatchToProps)(LogoutContainer)
我还将生命周期更改为didMount。你需要设置状态,重新渲染等(尽管redux会为你做这个)。 WillMount在这里没有任何意义。 React docs explains it.
请再次注意,此设置使用redux-thunk中间件。确保在商店中初始化它。 Redux-thunk docs.