代码之家  ›  专栏  ›  技术社区  ›  cc d

mapDispatchToProps反馈无法立即更新mapStateToProps

  •  1
  • cc d  · 技术社区  · 7 年前

    使用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 回复  |  直到 7 年前
        1
  •  0
  •   Shubham Khatri    7 年前

    具有 fetchLogin ,您似乎正在更新redux存储,而存储更新不会立即发生,因此 errorcode 不是在你发出动作后立即正确的

    您需要在中的errorcode上实现测试逻辑 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))