2017-05-02 58 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

相關問題