-1

I have a login form, which loads a loader when logging in. When login is unsucesful the loader should disappear and the buttons should reappear.

The loader is binded to this.state.loading.

if !this.state.loading it should show buttons (works on first load) when this.state.loading = true then it should show loader (this works too) I then run a promise using await async. then I run this.state.loading = false and it does not update.

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);
michael
  • 6,405
  • 14
  • 52
  • 98
  • Don't mutate the state directly, use setState, check this https://stackoverflow.com/questions/44570271/mutating-state-on-react-manually-then-calling-setstate/44570388#44570388 – Shubham Khatri Jan 17 '18 at 07:03
  • Possible duplicate of [Mutating state on React manually, then calling setState](https://stackoverflow.com/questions/44570271/mutating-state-on-react-manually-then-calling-setstate) – Viet Phan Jan 17 '18 at 07:05
  • thanks. Still learning react. – michael Jan 17 '18 at 07:15

1 Answers1

0

try

this.setState({loading: false}) 

instead of

this.state.loading = false;

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

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

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

kugtas
  • 107
  • 8