所以我正在尝试使用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在下面
{值:“”,突出显示:是,验证:是,验证错误:否,验证消息:“如果您在上面选择是,则此字段为必填。”
//此后不重新渲染!