mapDispatchToProps反馈无法立即更新mapStateToProps

时间:2018-05-08 06:11:41

标签: reactjs redux react-router react-redux

当使用redux来控制登录表单时,我遇到了一些奇怪的问题

下面的主要代码:

import ...

class LoginForm extends Component {
  constructor(props) {
    ...
  }
  componentWillUnmount(){
    clearTimeout(this.timeoutHandle);
  }
  handleName(evt) {
    this.setState({name: evt.target.value})
  }
  handlePwd(evt) {
    this.setState({pwd: evt.target.value})
  }
  handleLogin(evt) {
    const { name, pwd } = this.state
    const { errcode } = this.props.loginItems
    const { fetchLogin } = this.props
    let login = {
      name: name,
      pwd: pwd
    }
    fetchLogin(login)
    console.log(errcode)                                 <------ this line
    errcode === 0 && (
      this.timeoutHandle = setTimeout(() => {
        this.loginSuccess()
      }, 1000)
    )
  }
  loginSuccess() {
    ...
  }
  render() {
    const { errcode, errmsg } = this.props.loginItems
    const { name, pwd } = this.state
    return (
      <FlexContainerCenterColumn>
        <LoginInput
          onChange={this.handleName}
          value={name}>
        </LoginInput>
        <LoginInput
          type="password"
          onChange={this.handlePwd}
          value={pwd}>
        </LoginInput>
        <SubmitButton
          ...
          onClick={this.handleLogin}>
          Login
        </SubmitButton>
        <LoginFoot>
          {errcode === 1 && ...}
          {errcode === 0 && ...}
        </LoginFoot>
      </FlexContainerCenterColumn>
    );
  }
}

export default connect(
  (state) => ({
    loginItems: state.login.loginItems
  }),
  {changeRoute, fetchLogin}
)(withRouter(LoginForm))

fetchLogin是一种从服务器获取反馈的post方法

如果登录成功:

loginItems:{
  errcode: 0,
  errmsg: ''
}

并登录失败:

loginItems:{
  errcode: 1,
  errmsg: 'login failure'
}

此表单是受控制的组件

首次登录成功,console.log(errcode)返回1,然后再次登录,返回0

首次登录成功时,我应该如何获得正确的回复0

1 个答案:

答案 0 :(得分:0)

使用fetchLogin,您似乎正在更新redux商店,并且商店更新不会立即发生,因此在您发送操作后errorcode不会立即纠正< / p>

您需要在componentDidUpdate (In view of version 16.3.0, Previously you would use componentWillReceiveProps)方法

中的错误代码上实现测试逻辑
class LoginForm extends Component {
  constructor(props) {
    ...
  }
  componentWillUnmount(){
    clearTimeout(this.timeoutHandle);
  }
  handleName(evt) {
    this.setState({name: evt.target.value})
  }
  handlePwd(evt) {
    this.setState({pwd: evt.target.value})
  }
  handleLogin(evt) {
    const { name, pwd } = this.state
    const { fetchLogin } = this.props
    let login = {
      name: name,
      pwd: pwd
    }
    fetchLogin(login)
  }
  loginSuccess() {
    ...
  }
   componentDidUpdate(prevProps) {
     const {errorcode: prevErrorcode } = prevProps.loginItems;
     const {errorcode } = prevProps.loginItems;
     if(errorcode !== prevErrorcode) {
       errcode === 0 && (
          this.timeoutHandle = setTimeout(() => {
             this.loginSuccess()
          }, 1000)
       )
    }

  }
  render() {
    const { errcode, errmsg } = this.props.loginItems
    const { name, pwd } = this.state
    return (
      <FlexContainerCenterColumn>
        <LoginInput
          onChange={this.handleName}
          value={name}>
        </LoginInput>
        <LoginInput
          type="password"
          onChange={this.handlePwd}
          value={pwd}>
        </LoginInput>
        <SubmitButton
          ...
          onClick={this.handleLogin}>
          Login
        </SubmitButton>
        <LoginFoot>
          {errcode === 1 && ...}
          {errcode === 0 && ...}
        </LoginFoot>
      </FlexContainerCenterColumn>
    );
  }
}

export default connect(
  (state) => ({
    loginItems: state.login.loginItems
  }),
  {changeRoute, fetchLogin}
)(withRouter(LoginForm))