JSX在等待之后没有更新到绑定状态

时间:2018-01-17 06:47:11

标签: reactjs react-redux react-thunk

我有一个登录表单,它在登录时加载一个加载程序。当登录不成功时,加载程序应该消失并且按钮应该重新出现。

加载器绑定到this.state.loading。

如果!this.state.loading它应该显示按钮(适用于第一次加载) 当this.state.loading = true然后它应该显示加载器(这也适用) 然后我使用await async运行一个promise。 然后我运行this.state.loading = false并且它不会更新。

login.js:

import React, { Component } from "react";
import { connect } from "react-redux";
import * as actions from "../../actions";
import RoundLoader from "../elements/RoundLoader";
import Logo from "../img/image-center.png";
import "./login.css";

class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      errorMsg: "",
      loading: false
    };
    this.loginClicked = this.loginClicked.bind(this);
    console.log("loggedIn:", this.props.login);
  }

  async loginClicked() {
    try {
      var self = this;
      self.state.loading = true;
      console.log("this1", this);
      await this.props.loginUser(
        this.refs.email.value,
        this.refs.password.value
      );
      self.state.loading = false; //This has no effect on JSX
      if (this.props.login.success) {
        this.props.history.push("/");
      }
    } catch (ex) {
      this.state.loading = false;
      this.state.errorMsg = "Unable to connect to server";
      console.log("error", ex);
    }
  }

  render() {
    return (
      <div className="login-bg">
        <div className="container signForm">
          <div className="row back">
            <i className="material-icons">arrow_back</i>
            <a href="http://hbiaustralia.com.au/">Back to Site</a>
          </div>
          <div className="row login-container z-depth-4">
            <div className="col s12 l6 image-bg">
              <img className="hbi-logo" src={Logo} alt={"HBI Logo"} />
              <h1 className="center-align">
                Insurance <br /> Building Company
              </h1>
            </div>
            <div className="col s12 l6 login-form">
              <p className="center-align">Login to Trade Portal</p>
              <form>
                <div className="row">
                  <div className="input-field">
                    <input
                      id="email"
                      type="email"
                      className="validate"
                      ref="email"
                    />
                    <label htmlFor="email">Email</label>
                  </div>
                </div>
                <div className="row">
                  <div className="input-field">
                    <input
                      id="password"
                      type="password"
                      className="validate"
                      ref="password"
                    />
                    <label htmlFor="password">Password</label>
                  </div>
                </div>
                {!this.state.loading ? (       {/* HERE IS THE IF STATEMENT */}
                  /* If Not Loading then show  Login buttons */
                  <div>
                    <div className="row">
                      <button
                        className="btn waves-effect waves-light"
                        type="button"
                        name="action"
                        onClick={this.loginClicked}
                      >
                        Submit
                      </button>
                      <a href="/subcontractor" className="register">
                        Register here
                      </a>
                    </div>
                  </div>
                ) : (
                  /* If Loading then show Loader not Login buttons */
                  <div className="row">
                    <div className="col s12 center">
                      <RoundLoader />
                    </div>
                  </div>
                )}
            <div className="row">
                  <div style={{ textAlign: "center", color: "red" }}>
                    {this.props.login.message}
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

function mapStateToProps({ login }) {
  return { login };
}

export default connect(mapStateToProps, actions)(Login);

1 个答案:

答案 0 :(得分:0)

this.setState({loading: false}) 

而不是

this.state.loading = false;

https://reactjs.org/docs/react-component.html#setstate

来自https://reactjs.org/docs/react-component.html#state

  

永远不要直接改变this.state,因为之后调用setState()可能会替换你所做的突变。把this.state看作是不可变的。