使用计算键修改状态对象时,我是否正在改变状态?

时间:2019-09-11 17:27:14

标签: javascript reactjs

所以我正在尝试使用React执行实时表单验证。

我有一个单选按钮,询问用户是否已经有一个网站。如果他的回答是,我需要验证现有的网站文本输入。如果答案是否定的,则无需验证现有的网站字段并允许用户提交。

此状态重新设计由单选按钮“是”和“否”控制。

在componentDidUpdate中,我检查重新设计是否已更改。如果有,我通过调用this.validate('existing_website')再次执行验证。

validate函数检查this.state.redesign是否为true以及this.state.exsting_website ==“”。如果是,则将输入字段的validation_error设置为true。

我无法达到预期的效果。当我单击“是”单选按钮时,提交按钮仍然保持活动状态。

在其中可以看到,当我单击“是”时,componentDidUpdate被调用,this.validate('existing_website')也被调用。

this.setState({[input_name]:input},()=>{  
        console.log(this.state[input_name]);
});
验证功能中的

还记录了我看到的更新状态。state.existing_website.validation_error设置为true。

但是此后组件不会重新呈现,并且按钮保持活动状态。

知道为什么会这样吗?请帮帮我!非常感谢。下面是我的完整代码。

constructor(props){
  super(props);
  this.state={
    existing_website:{value:'',validate:true,validation_error:false,validation_message:"This field is necessary if you have selected yes above."},
    redesign:false
  }
  this.validate = this.validate.bind(this);
}
getLabelAndInput(label,type,input_name){
     var field= <input type={type} name={input_name} value={this.state[input_name].value} onChange={(e)=>this.setInputValue(input_name,e.target.value)} onBlur={()=>this.inputBlur(input_name)} onFocus={()=>this.inputFocus(input_name)} className="width-100"/>
     return (
        <div className={"form-group"}>
          <label>{label}</label>
          {field}
          {this.state[input_name].validation_error?
            <p className="error">{this.state[input_name].validation_message}</p>
            :
            ''
          }
        </div>
      );
}
validate(input_name){
      var input = Object.assign({},this.state[input_name]);
      if(input.validate){
          if(input_name=="existing_website"){
          if(this.state.redesign && input.value==""){
            console.log('existing website validation error')
            input.validation_error = true;
          }
          else{
            console.log('existing website no validation error')
            input.validation_error = false;
          }
        }
      }
      this.setState({[input_name]:input},()=>{  
        console.log(this.state[input_name]);
      }); // Is this line mutating the state??
}
componentDidUpdate(prevProps,prevState){
      if(prevState.redesign != this.state.redesign){
        console.log('redesign change')
        this.validate('existing_website');
      }
}
render(){
    console.log(this.state.existing_website.validation_error);
    let btnSubmit = <button type="button" className="btn btn-primary" onClick={()=>this.handleSubmit()}>Submit</button>
    if(this.state.existing_website.validation_error){
        btnSubmit = <button type="button" className="btn btn-secondary" disabled>Submit</button>
    }
    return(
            <div className="form-group">

               <label className="highlight">Do you already have a website?</label>
               <span onClick={()=>this.setState({redesign:false},()=>{this.likedWebsitesRef.current.focus()})}><input type="radio" name="redesign" checked={!this.state.redesign}/> <span className="service_type_text">No</span></span>
               <span onClick={()=>this.setState({redesign:true})}><input type="radio" name="redesign" checked={this.state.redesign}/> <span className="service_type_text">Yes</span></span>

            </div>

           { this.state.redesign &&

              <div className="form-group">
                  {this.getLabelAndInput('Link to existing website','text','existing_website')}
              </div>

            }

            {btnSubmit}
    );
}

编辑: 我的console.log输出:

下面的布尔值来自render函数中的console.log,并指示this.state.existing_website.validation_error的值。

false //由于this.state.redesign的更改而第一次重新呈现

重新设计更改//由于上述更改,componentDidUpdate中的console.log

现有网站验证错误//验证函数被调用

false //再次渲染。这本应在this.setState之后发生,而console.logs在下面

{值:“”,突出显示:是,验证:是,验证错误:否,验证消息:“如果您在上面选择是,则此字段为必填。”

//此后不重新渲染!

0 个答案:

没有答案