javascript - 简单的 ReactJS 表单验证问题

标签 javascript reactjs

我在学习 reactjs 的同时正在开发一个简单的 Reactjs 登录表单。现在我的表单在浏览器上正确呈现。但是它的验证不起作用,尽管我已经为表单定义了验证规则。它只有两个字段,一个用于电子邮件,另一个用于密码。和登录按钮。以下是我的 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'));

最佳答案

第一个错误是在你提到的输入标签内

onChange={this.props.handleChange}

这意味着事件将冒泡到父类 (LoginForm),因此不会调用 MyInput 的 handleChange。从你再次调用父函数的地方。所以把它改成

onChange={this.handleChange}

第二个错误出现在 MyInput 的 isValid 方法中,您在其中使用不适用于 React 的 javascript 操作 DOM。

input.classList.add('error');//add class error
input.nextSisling.textContent=this.props.messageRequired;//show error message

(虽然我说的是 nextSibling)

在我看来,维护错误状态并将其设置在 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>
    );
}
});

关于javascript - 简单的 ReactJS 表单验证问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36081209/

相关文章:

javascript - 不可变 JS - 如何按降序对日期进行排序

javascript - 如何删除 eslint 插件 eslint-plugin-jsx-a11y?

javascript - 在 AngularJS 和 PHP 中允许 CORS

javascript - 三.JS 未捕获的 ReferenceError : OrbitControls is not defined

javascript - 将数字转换为字符串再转换为数字以删除点

reactjs - 如何禁用 React/ElectronJS 应用程序的 devtools 源映射

javascript - 值的状态未更新

javascript - 如何在 AngularJS 中与另一个 Controller 共享 $scope 变量?

javascript - 跨不同容器 div 的 ngFor 数据长度为 4

javascript - 单击标记时不显示 react 传单弹出窗口