Thomas Dupont
Thomas Dupont

Reputation: 427

React : Template Style property is not update by setState

Considering my code example (a forgot password form)

import React, { PropTypes, Component } from 'react';
import $ from 'jquery';
import ManageCountry from '../ManageCountry';

import './style.css';
import {CONFIG} from '../const.js';

export default class Forgotpwd extends Component {

    state = {
        passwordText : "",
        passwordTextConfirm : "",
        expirated_reset_request: "none"
    }

    trad = {};
    constructor () {
        super();
        ManageCountry.applyTradToState("single_sign_on", this.trad, () => {
            var trad = this.trad.message.reset_password_form[0];
            this.template = (
                <div id="forgotpwd-form" role="form" >
                    <h3>{trad.form_title}</h3>
                    <p>{trad.form_desc}</p>
                    <div className="form-group">
                        <label htmlFor="emailfpwd">{trad.password_label}</label>
                        <input onChange={(password) => this.setState({passwordText:password.target.value})}  type="email" id="emailfpwd"  className="form-control" placeholder={trad.password_label}/>
                    </div>
                    <div className="form-group">
                        <label htmlFor="emailfpwd">{trad.password_confirmation_label}</label>
                        <input onChange={(password) => this.setState({passwordTextConfirm:password.target.value})}  type="email" id="emailfpwd"  className="form-control" placeholder={trad.password_label}/>
                    </div>
                    <p id="expirated_reset_request" style={{display : this.state.expirated_reset_request}}>{trad.expirated_reset_request}</p>
                    <div className="form-group">
                        <div className="row">
                            <div className="col-sm-6 col-sm-offset-3">
                                <button onClick={this.resetPwd.bind(this)}  className="form-control btn btn-login">{trad.submit_label}</button>
                            </div>
                        </div>
                    </div>
                </div>
            );
        });
    }

    resetPwd () {
        var validate = this.validatePassword();
        var token =  window.location.href.split('=').pop();
        console.log(token);
        if(!token.match(new RegExp(/^[a-f\d.]+$/))) {
            alert(this.trad.message.reset_password_form[0].bad_reset_request);
            return false;
        }
        if(validate.success) {
            $.post(CONFIG.APIURL+"user/forgotpwd/"+token, {password: this.state.passwordText}, (r) => {
                if(r.success) {
                    window.location = "/"+ManageCountry.getUrlRoute()+"/login";
                } else {
                    //$('#expirated_reset_request').css('display', 'block');
                    this.setState({expirated_reset_request : "block"});
                    console.log(this.state.expirated_reset_request);
                    //'block', but in HTML, the style is always 'none'
                }
            }, 'JSON');
        }
    }

    validatePassword () {
        if(this.state.passwordText != this.state.passwordTextConfirm) return {success : false, msg : "Les mots de passe ne correspondent pas"};
        if(this.state.passwordText.length < 8) return {success : false, msg : "Le mot de passe doit faire 8 caractères au minimum"};
        return {success : true};
    }

    render = () => {
        return this.template;
    }
}

I want to update a state property with a form error, here the expirated_reset_request property.

So As you can see, the onClick perform the resetPwd function and in the $.post callback, I am updating the state to change the display from none (initial) to block.

The console.log just after are saying to me that state is up-to-date but the style property is never changing in the HTML (always none)

Did I forget something?

Thanks in advance

Upvotes: 0

Views: 318

Answers (1)

Kraylog
Kraylog

Reputation: 7553

From what I can see, the this.template variable gets populated only once.

It makes sense, then, that it never changes.

To have it re-evaluated each time, change it into a function:

this.template = () => (
  <div ...
)

Upvotes: 1

Related Questions