javascript - 尝试验证表单时出现“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>
);
}
}
解决方案
需要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
编辑:更新的类构造函数
推荐阅读
- authentication - 仅将生命周期最长的 JWT 的时间存储到数据库中,而不是整个 JWT
- angular - 如何在 Angular 测试中打印调试消息?
- reactjs - 无法从 gatbsy 中的 graphQL 获取数据
- node.js - updateOne 方法不更新模型,而是抛出错误
- javascript - 如何在 React 中使用 Axios 进行历史记录
- r - R中的行到列转换
- c# - 在C#中转换Long中的十进制值时出现类型转换错误
- swiftui - iOS 14 的 iOS 应用和小部件之间的通信
- c# - c# HttpClient post response content-type application/json
- excel - 如何发送具有自定义时间和与会者的多个 Outlook 邀请?