React-Redux如何在加载时自动触发动作

时间:2017-05-02 03:40:06

标签: javascript reactjs react-redux

新手。

我有一个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;甚至没有被称为..

1 个答案:

答案 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.