首页 > 解决方案 > 尝试验证表单时出现“TypeError”

问题描述

我试图在我的表单中添加一个验证函数,但是当我测试它时,我得到“未捕获的类型错误:无法读取未定义的属性 'handleValidation'”。由于我是 reactjs 新手(这是我第一个使用 react 制作的 webapp),我似乎无法找到错误所在。此表单的行为是:当用户单击提交时,它首先执行验证,然后如果有效则通过电子邮件提交表单(为此我使用 emailjs)。就像我说的,它在验证步骤上失败了(而其他一切都很好,甚至是电子邮件)。我希望你能帮助我,这是我的表单组件:

class ContactForm extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        fields: { 'user_name': "", 'user_email': "" },
        errors: {}
    };
}
//Functions to handle form validation

handleValidation() {
    let fields = this.state.fields;
    let errors = {};
    let formIsValid = true;

    //Name
    if (!fields["user_name"]) {
        formIsValid = false;
        errors["user_name"] = "Non può essere vuoto!";
    }

    if (typeof fields["user_name"] !== "undefined") {
        if (!fields["user_name"].match(/^[a-zA-Z]+$/)) {
            formIsValid = false;
            errors["user_name"] = "Solo lettere";
        }
    }

    //Email
    if (!fields["user_email"]) {
        formIsValid = false;
        errors["user_email"] = "Non può essere vuoto!";
    }

    if (typeof fields["user_email"] !== "undefined") {
        let lastAtPos = fields["user_email"].lastIndexOf('@');
        let lastDotPos = fields["user_email"].lastIndexOf('.');

        if (!(lastAtPos < lastDotPos && lastAtPos > 0 && fields["user_email"].indexOf('@@') == -1 && lastDotPos > 2 && (fields["user_email"].length - lastDotPos) > 2)) {
            formIsValid = false;
            errors["user_email"] = "Email non valida";
        }
    }

    this.setState({ errors: errors });
    return formIsValid;
}

handleChange(field, e) {
    let fields = this.state.fields;
    fields[field] = e.target.value;
    this.setState({ fields });
}


sendEmail(e) {
    let submitSuccess = document.getElementById('success');
    let submitFailed = document.getElementById('failed');
    let contactNumber = document.getElementById('contact_number');
    let userName = document.getElementById('user_name');
    let userMail = document.getElementById('user_email');
    let userMessage = document.getElementById('message');


    e.preventDefault();
    //Generate random 5-digit number for the contact number
    contactNumber.value = Math.random() * 100000 | 0;

    if (this.handleValidation) {
        emailjs.sendForm(/*informations to send email*/)
            .then((result) => {
                console.log(result.text);
                submitSuccess.style.display = 'block';
                userName.style.value = '';
                userMail.style.value = '';
                userMessage.style.value = '';
            }, (error) => {
                console.log(error.text);
                submitFailed.style.display = 'block';
            })
    } else {
        alert("Ci sono errori nel form");
    };

}

render() {
    return (
        <form className="contact-form" onSubmit={this.sendEmail}>
            <input type="hidden" id="contact_number" name="contact_number" value="" />
            <label style={{ fontSize: '1.3em' }}>Nome</label>
            <input type="text" name="user_name" id="user_name" style={InputFormCSS} onChange={this.handleChange.bind(this, "user_name")} value={this.state.fields["user_name"]} required />
            <label style={{ fontSize: '1.3em' }}>Email</label>
            <input type="email" name="user_email" id="user_mail" style={InputFormCSS} onChange={this.handleChange.bind(this, "user_email")} value={this.state.fields["user_email"]} required />
            <label style={{ fontSize: '1.3em' }}>Message</label>
            <textarea name="message" id="message" style={TextareaFormCSS} required />
            <input type="submit" value="Invia" />
            <p id="success" style={{ display: 'none', backgroundColor: 'green', color: 'white', fontSize: '1.1em', borderRadius: 5, padding: 10 }}>Il messaggio è stato inviato con successo</p>
            <p id="failed" style={{ display: 'none', backgroundColor: 'red', color: 'white', fontSize: '1.1em', borderRadius: 5, padding: 10 }}>Non è stato possibile inviare il messaggio</p>
        </form>


    );
}

}

标签: javascriptreactjs

解决方案


需要handleValidation在构造函数中绑定函数。

class TodoApp extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
        fields: { user_name: "", user_email: "" },
        errors: {}
    };
    this.handleValidation = this.handleValidation.bind(this);
    this.sendEmail = this.sendEmail.bind(this);
    this.handleChange = this.handleChange.bind(this);
    }
//Functions to handle form validation

handleValidation() {
    let fields = this.state.fields;
    let errors = {};
    let formIsValid = true;

    //Name
    if (!fields["user_name"]) {
        formIsValid = false;
        errors["user_name"] = "Non può essere vuoto!";
    }

    if (typeof fields["user_name"] !== "undefined") {
        if (!fields["user_name"].match(/^[a-zA-Z]+$/)) {
            formIsValid = false;
            errors["user_name"] = "Solo lettere";
        }
    }

    if (!fields["user_email"]) {
        formIsValid = false;
        errors["user_email"] = "Non può essere vuoto!";
    }

    if (typeof fields["user_email"] !== "undefined") {
        let lastAtPos = fields["user_email"].lastIndexOf('@');
        let lastDotPos = fields["user_email"].lastIndexOf('.');

        if (!(lastAtPos < lastDotPos && lastAtPos > 0 && fields["user_email"].indexOf('@@') == -1 && lastDotPos > 2 && (fields["user_email"].length - lastDotPos) > 2)) {
            formIsValid = false;
            errors["user_email"] = "Email non valida";
        }
    }

    this.setState({ errors: errors });
    return formIsValid;
}

handleChange(field, e) {
    let fields = this.state.fields;
    fields[field] = e.target.value;
    this.setState({ fields });
}


sendEmail(e) {
    let submitSuccess = document.getElementById('success');
    let submitFailed = document.getElementById('failed');
    let contactNumber = document.getElementById('contact_number');
    let userName = document.getElementById('user_name');
    let userMail = document.getElementById('user_email');
    let userMessage = document.getElementById('message');


    e.preventDefault();
    //Generate random 5-digit number for the contact number
    contactNumber.value = Math.random() * 100000 | 0;

    if (this.handleValidation) {
        emailjs.sendForm(/*informations to send email*/)
            .then((result) => {
                console.log(result.text);
                submitSuccess.style.display = 'block';
                userName.style.value = '';
                userMail.style.value = '';
                userMessage.style.value = '';
            }, (error) => {
                console.log(error.text);
                submitFailed.style.display = 'block';
            })
    } else {
        alert("Ci sono errori nel form");
    };
}
  render() {
    return (
        <form className="contact-form" onSubmit={this.sendEmail}>
            <input type="hidden" id="contact_number" name="contact_number" value="" />
            <label style={{ fontSize: '1.3em' }}>Nome</label>
            <input type="text" name="user_name" id="user_name" onChange={this.handleChange.bind(this, "user_name")} value={this.state.fields["user_name"]} required />
            <label style={{ fontSize: '1.3em' }}>Email</label>
            <input type="email" name="user_email" id="user_mail" onChange={this.handleChange.bind(this, "user_email")} value={this.state.fields["user_email"]} required />
            <label style={{ fontSize: '1.3em' }}>Message</label>
            <textarea name="message" id="message" required />
            <input type="submit" value="Invia" />
            <p id="success" style={{ display: 'none', backgroundColor: 'green', color: 'white', fontSize: '1.1em', borderRadius: 5, padding: 10 }}>Il messaggio è stato inviato con successo</p>
            <p id="failed" style={{ display: 'none', backgroundColor: 'red', color: 'white', fontSize: '1.1em', borderRadius: 5, padding: 10 }}>Non è stato possibile inviare il messaggio</p>
        </form>


    );
}
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))

第二个场景

class TodoApp extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
        fields: { user_name: "", user_email: "" },
        errors: {}
    };
    }
//Functions to handle form validation

handleValidation = () => {
    let fields = this.state.fields;
    let errors = {};
    let formIsValid = true;

    //Name
    if (!fields["user_name"]) {
        formIsValid = false;
        errors["user_name"] = "Non può essere vuoto!";
    }

    if (typeof fields["user_name"] !== "undefined") {
        if (!fields["user_name"].match(/^[a-zA-Z]+$/)) {
            formIsValid = false;
            errors["user_name"] = "Solo lettere";
        }
    }

    if (!fields["user_email"]) {
        formIsValid = false;
        errors["user_email"] = "Non può essere vuoto!";
    }

    if (typeof fields["user_email"] !== "undefined") {
        let lastAtPos = fields["user_email"].lastIndexOf('@');
        let lastDotPos = fields["user_email"].lastIndexOf('.');

        if (!(lastAtPos < lastDotPos && lastAtPos > 0 && fields["user_email"].indexOf('@@') == -1 && lastDotPos > 2 && (fields["user_email"].length - lastDotPos) > 2)) {
            formIsValid = false;
            errors["user_email"] = "Email non valida";
        }
    }

    this.setState({ errors: errors });
    return formIsValid;
}

handleChange = (field, e) => {
    let fields = this.state.fields;
    fields[field] = e.target.value;
    this.setState({ fields });
}


sendEmail = (e) => {
    let submitSuccess = document.getElementById('success');
    let submitFailed = document.getElementById('failed');
    let contactNumber = document.getElementById('contact_number');
    let userName = document.getElementById('user_name');
    let userMail = document.getElementById('user_email');
    let userMessage = document.getElementById('message');


    e.preventDefault();
    //Generate random 5-digit number for the contact number
    contactNumber.value = Math.random() * 100000 | 0;

    if (this.handleValidation) {
        emailjs.sendForm(/*informations to send email*/)
            .then((result) => {
                console.log(result.text);
                submitSuccess.style.display = 'block';
                userName.style.value = '';
                userMail.style.value = '';
                userMessage.style.value = '';
            }, (error) => {
                console.log(error.text);
                submitFailed.style.display = 'block';
            })
    } else {
        alert("Ci sono errori nel form");
    };
}
  render() {
    return (
        <form className="contact-form" onSubmit={this.sendEmail}>
            <input type="hidden" id="contact_number" name="contact_number" value="" />
            <label style={{ fontSize: '1.3em' }}>Nome</label>
            <input type="text" name="user_name" id="user_name" onChange={this.handleChange.bind(this, "user_name")} value={this.state.fields["user_name"]} required />
            <label style={{ fontSize: '1.3em' }}>Email</label>
            <input type="email" name="user_email" id="user_mail" onChange={this.handleChange.bind(this, "user_email")} value={this.state.fields["user_email"]} required />
            <label style={{ fontSize: '1.3em' }}>Message</label>
            <textarea name="message" id="message" required />
            <input type="submit" value="Invia" />
            <p id="success" style={{ display: 'none', backgroundColor: 'green', color: 'white', fontSize: '1.1em', borderRadius: 5, padding: 10 }}>Il messaggio è stato inviato con successo</p>
            <p id="failed" style={{ display: 'none', backgroundColor: 'red', color: 'white', fontSize: '1.1em', borderRadius: 5, padding: 10 }}>Non è stato possibile inviare il messaggio</p>
        </form>


    );
}
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))

参考:https ://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

编辑:更新的类构造函数


推荐阅读