2017-05-02 60 views
1

对此不熟悉。React-Redux如何在加载时自动启动一个动作

我有一个React-Redux应用程序,我在其中加载了一个JWT令牌,结果该应用程序以授权设置=指示状态为“true”。这工作,它现在知道它的授权。

在导航栏上,我有一个“注销”选项,我想单击并相应地从本地存储中删除JWT,并重新呈现导航栏以显示“登录”。

的一切都在这里首先是与测试授权等的导航栏:

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

请注意,我只是一个包含“isAuthorized”三元如果授权来显示不同的链接。当点击“退出”应该重新检查三元和更新...

注销

我有一个在导入到减速机文件的另一个文件名为“clearJWT”功能的其他部分。

export const clearJwt =() => { 
    localStorage.removeItem(TOKEN_KEY) 
} 

的事情是不存在的“事件”,我可以挂一个动作关是它应该只呈现“注销...”,然后用上面的功能从本地存储删除JWT。

我有,目前结合了行动和减速器,但稍后将分开。

所以我有三个文件。顶部带有动作的减速器。注销容器=>“logoutContainer”和注销这是一个非常简单的班轮。

这是我设置的代码。

在减速机文件中的动作(称为reducer.js):

export const logoutUser =() => 
    (dispatch, getState) => { 
    clearJwt() 
     ({ type: LOGOUT_USER }) 
    } 

为LOGOUT_USER减速机选项:

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()上调用这个动作,它会调用“logoutUser()”,它将会更新e状态,同时也呈现“退出..”并更新菜单栏。

我发现this问题,这表明我应该使用“componentDidMount()”,但它并没有改变任何东西和注销未启用还是叫......

我不认为这种做法是正确的。(以及它不工作,所以这是一条线索)

如何点击NavBar上的“注销”链接,转到“LogoutContainer”,自动调用动作(logoutUser())并重新渲染页面以及使用Navbar重新检查“授权”状态并认识到它现在还没有授权并重新导航导航栏?

这是否是正确的方法呢?

在mycase“logoutUser()”心不是甚至被称为..

+0

难道你不应该用道具调用logoutUser()吗?像这样:this.props.logoutUser() – Shota

回答

1

我需要张贴此作为一个答案,因为它能够长注释,但首先把它作为一个建议,一些代码清理。你必须自己测试它。

首先你的动作。这是写作行为的“thunk action”处理方式。你可以看到它是一个函数返回另一个函数(因此thunk)。在你的代码中,你从来没有真正调用它(这就是为什么没有被调用,它停在thunk上。如果你想使用redux-thunk中间件来阅读如何使用它,它有点不同于“正常”调度。Redux-thunk docs.

其次你不是要求调度员,所以你的动作不会被调用和终极版惯于重新渲染您的应用程序。

export const logoutUser =() => 
    (dispatch, getState) => { 
    clearJwt() 
    dispatch({ type: LOGOUT_USER }) //Call the dispatcher with your action 
    } 

在容器中,你需要正确使用的thunk和行动,通过@提及si2030中的评论。

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。你需要设置状态,重新渲染等(尽管如此,REDX会为你做这件事)。 WillMount在这里没有任何意义。 React docs explains it.

请再次注意,此设置使用了redux-thunk中间件。确保您已在商店中初始化它。 Redux-thunk docs.

+0

它只是现在才意识到,你有两种类型的道具,一种是来自状态,这是使用“mapStateToProps”的地方,我不明白但是另一套道具或道具(大部分),就我而言,这是一个功能。它在行动中创造的另一个道具。用这个来激发这个动作,它与状态道具无关......我在半小时前得到了这个,从我迄今为止读到的内容来看,这对我来说并不明显。一旦你将“this.props”放在了logoutUser()函数的前面,它就可以工作。感谢您指出这一点..它现在更有意义。 – si2030

相关问题