react-google-recaptcha验证异常:表单未验证即可提交问题求助
修复React联系表单的reCAPTCHA验证问题
Hey,我看了你的代码,发现两个核心问题导致了表单刷新和验证逻辑异常,咱们一步步来修复:
问题根源
未全局阻止表单默认提交行为
你当前只在this.state.verified为true时调用event.preventDefault(),但当用户未完成reCAPTCHA验证就点击提交时,代码走到else分支,没有阻止表单的默认提交行为,浏览器就会用GET方式提交表单,导致页面跳转刷新。错误提示的显示逻辑颠倒
当前代码是验证通过时才显示错误提示,这和咱们的需求完全相反——应该是未验证且触发提交时,才显示"Please verify the ReCaptcha."的提示。
修改后的完整代码
import React from 'react' import ReCAPTCHA from "react-google-recaptcha"; import {Container, Row, Col, Form, Button } from 'react-bootstrap' import '../styles/contact.css' class Contact extends React.Component { constructor(props, context) { super(props, context); this.state = { name: '', email: '', company: '', content: '', showSuccess: false, submitting: false, verified: false, reply: '' }; this.handleSuccess = this.handleSuccess.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.handleInputChange = this.handleInputChange.bind(this); this.onChange = this.onChange.bind(this); } onChange = (value) => { console.log("Captcha value:", value); this.setState({ verified: true, reply: '' }) // 验证通过时清空错误提示 }; handleInputChange = event => { const target = event.target const value = target.value const name = target.name this.setState({ [name]: value, }) } handleSuccess = () => { this.setState({ name: '', email: '', company: '', content: '', showSuccess: true, submitting: false, verified: false, // 重置验证状态,方便用户再次提交 reply: '' }) } handleSubmit = event => { // 第一步:先阻止表单默认提交行为,不管验证是否通过 event.preventDefault(); const url = 'https://xxxxxxxx.execute-api.eu-central-1.amazonaws.com/dev/email/send'; // 如果正在提交,直接返回,防止重复提交 if (this.state.submitting) return; const payload = { name: this.state.name, email: this.state.email, company: this.state.company, content: this.state.content } if (this.state.verified) { this.setState({ submitting: true, showSuccess: false }) fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }) .then(this.handleSuccess) .catch(error => { alert(error); this.setState({ submitting: false, verified: false }) // 失败后重置状态 }) } else { this.setState({ reply: "Please verify the ReCaptcha.", showSuccess: false }) } } render() { return ( <section id="contact" name="#contact"> <Container> <Row className="align-items-center"> <Col lg={{span: 5, order: 1}} xs={{ span: 12, order: 2}} className="form-background"> <Form id="contact-form-bottom" onSubmit={this.handleSubmit}> <h4 className="h4">Don't be shy, say hi!</h4> <Form.Group controlId="formBasicName"> <Form.Label>Full Name</Form.Label> <Form.Control as="input" type="text" placeholder="Enter your first name & surname" name="name" value={this.state.name} onChange={this.handleInputChange} required /> </Form.Group> <Form.Group controlId="formBasicEmail"> <Form.Label>Email address</Form.Label> <Form.Control as="input" type="email" placeholder="Enter your email address" name="email" value={this.state.email} onChange={this.handleInputChange} required /> <Form.Text className="text-muted"> We'll never share your email with anyone else. </Form.Text> </Form.Group> <Form.Group controlId="formBasicCompany"> <Form.Label>Company Name</Form.Label> <Form.Control as="input" type="text" placeholder="Enter the name of your company" name="company" value={this.state.company} onChange={this.handleInputChange} required /> </Form.Group> <Form.Group controlId="exampleForm.ControlTextarea1"> <Form.Label>Details</Form.Label> <Form.Control as="textarea" rows="3" placeholder="How can we help you?" name="content" value={this.state.content} onChange={this.handleInputChange} required /> </Form.Group> <ReCAPTCHA className="g-recaptcha" sitekey="XXXXXXXXXXXXXXXXXXX" onChange={this.onChange} theme="dark" /> {/* 修正错误提示的显示条件:未验证且有错误消息时显示 */} { !this.state.verified && this.state.reply && <p id="error" className="error">{this.state.reply}</p> } { this.state.showSuccess && <p id="success" className="success">Thank you, we will be in touch asap.</p> } {/* 添加按钮禁用状态,防止重复提交 */} <Button id="submit" variant="primary" type="submit" disabled={this.state.submitting}> {this.state.submitting ? "Submitting..." : "Submit"} </Button> </Form> </Col> </Row> </Container> </section> ) } } export default Contact
关键修改说明
- 全局阻止默认提交:在
handleSubmit函数最开头就调用event.preventDefault(),确保所有提交逻辑都由JavaScript处理,不会触发浏览器默认的表单跳转。 - 修正错误提示逻辑:把错误提示的显示条件改成
!this.state.verified && this.state.reply,只有未验证且存在错误消息时才显示提示。 - 优化状态管理:
- 验证通过时清空错误消息
- 提交成功或失败后重置
verified状态,方便用户再次提交 - 添加
submitting状态判断,防止重复提交,同时给用户显示提交中的状态提示
- 修正Form的controlId:原来多个Form.Group用了相同的
formBasicEmail,改成了唯一的ID,避免React Bootstrap的内部逻辑冲突。
这样修改后,表单就能按预期工作:未完成reCAPTCHA验证时点击提交,会显示错误提示且不会刷新页面;验证通过后,表单通过fetch提交,页面保持无刷新,提交成功后清空表单并显示成功提示。
内容的提问来源于stack exchange,提问作者Philipp Laurim
相关产品推荐
相关产品推荐

