我正在开发一个简单的Reactjs登录表单,而我正在学习reactjs.Now我的表单在浏览器上正确呈现。但是虽然我已经为表单定义了验证规则但它的验证不起作用。它只有两个字段一个用于电子邮件,另一个用于密码。登录按钮。以下是我的Reactjs代码,
//React component for input component
var MyInput=React.createClass({
//onchange event
handleChange: function(e){
this.props.onChange(e.target.value);
var isValidField=this.isValid(e.target);
},
//validate function
isValid: function (input){
//check required field
if (input.getAttribute('required') !=null && input.value==="") {
input.classList.add('error');//add class error
input.nextSisling.textContent=this.props.messageRequired;//show error message
return false;
}
else{
input.classList.remove('error');
input.nextSisling.textContent="";
}
//check data type
if (input.getAttribute('type') == "email" && input.value !="") {
if(!this.validateEmail(input.value)){
input.classList.add('error');
input.nextSisling.textContent=this.props.messageEmail;
return false;
}
else{
input.classList.remove('error');
input.nextSisling.textContent="";
}
}
return true;
},
//email validation function
validateEmail: function(value){
var re=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0- 9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z] {2,}))$/;
return re.test(value);
},
componentDidmount: function(){
if(this.props.onComponentMounted){
this.props.onComponentMounted(this);//register the input in form
}
},
//render
render:function(){
var inputField;
inputField = <input type={this.props.type} ref={this.props.name} name= {this.props.name} className='form-control' required={this.props.isrequired} onChange={this.props.handleChange}/>;
return(
<div className="form-signin">
<label>{this.props.htmlfor}:</label>
{inputField}
<span className="error"></span>
</div>
);
}
});
//React component for generate form
var LoginForm=React.createClass({
//get initial statement
getInitialState: function(){
return {
Username: '',
Userpassword: '',
Fields: [],
ServerMessage: ''
}
},
//submit function
handleSubmit: function(e){
e.preventDefault();
//validate entire form
var validForm=true;
this.state.Fields.forEach(function(field){
if(typeof field.isValid === "function"){
var validField=field.isValid(field.refs[field.props.name]);
validForm=validForm && validField;
}
});
//after validation, data post to server
if (validForm) {
var d = {
Username: this.state.Username,
Userpassword: this.state.Userpassword
}
$.ajax({
type: "POST",
url: this.props.actionUrl,
data: d,
dataType:"json",
success: function(data){
//will clear form upon data submitted
this.setState({
Username: '',
Userpassword: '',
ServerMessage: data.message
});
}.bind(this),
error: function(e){
console.log(e);
alert('Something went wrong..Please try again!');
}
});
}
},
//handle change username
onChangeUsername: function(value){
this.setState({
Username: value
});
},
//handle change password
onChangePassword: function(value){
this.setState({
Userpassword: value
});
},
//register input controls
register: function(field){
var s=this.state.Fields;
s.push(field);
this.setState({
Fields: s
});
},
//render
render: function(){
//render form
return(
<form name="loginForm" noValidate onSubmit={this.handleSubmit}>
<MyInput type={'email'} value={this.state.Username} label= {'Username'} htmlfor={'Username'} name={'Username'} isrequired={true}
onChange={this.onChangeUsername} onComponentMounted={this.register} messageRequired={'Invalid username'}/>
<MyInput type={'password'} value={this.state.Userpassword} label={'Password'} htmlfor={'Password'} name={'Userpassword'} isrequired={true}
onChange={this.onChangePassword} onComponentMounted={this.register} messageRequired={'Invalid Password'}/>
<button type="submit" className="btn btn-lg btn-primary btn-block">SignIn</button>
<p className="servermessage">{this.state.ServerMessage}</p>
</form>
);
}
});
//Render react component into the page
ReactDOM.render(<LoginForm actionUrl="UserLogin"/>,document.getElementById('ReactJSForm'));
答案 0 :(得分:1)
第一个错误是你提到的输入标签内部
onChange={this.props.handleChange}
这意味着事件将冒泡到父类(LoginForm),因此不会调用MyInput的handleChange。从那里你再次称之为父功能。所以改为
onChange={this.handleChange}
第二个错误出现在MyInput的isValid方法中,您正在使用javascript操作DOM,这不适用于反应。
input.classList.add('error');//add class error
input.nextSisling.textContent=this.props.messageRequired;//show error message
(虽然我的意思是nextSi b ling)
在我看来,维护一个错误状态并将其设置在isValid中,即返回的值。基于此做了上述操作。
之类的东西render:function(){
var inputField;
var inputClass ='form-control';
var errorMsg = '';
if( this.state.isError){// guessing you set state isError to true/false inside isValid
inputClass += ' error';
errorMsg = this.props.messageEmail;
}
inputField = <input type={this.props.type} ref={this.props.name} name= {this.props.name} className={inputClass} required={this.props.isrequired} onChange={this.handleChange}/>;
return(
<div className="form-signin">
<label>{this.props.htmlfor}:</label>
{inputField}
<span className="error">{errorMsg}</span>
</div>
);
}
});