0

我有以下用于联系表单的 React 组件:

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
        })
    };


    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,
        })
    }

    handleSubmit = event => {

        const url = 'https://xxxxxxxx.execute-api.eu-central-1.amazonaws.com/dev/email/send';

        this.setState({
            submitting: true
          })

        const payload = {
            name: this.state.name,
            email: this.state.email,
            company: this.state.company,
            content: this.state.content
        }

        if (this.state.verified) {
            fetch(url, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload),
            })
            .then(this.handleSuccess)
            .catch(error => alert(error))
            event.preventDefault()
        }
        else {this.setState({reply: "Please verify the ReCaptcha."})}
    }

    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="formBasicEmail">
                                    <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="formBasicEmail">
                                    <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" 
                                        type="text" 
                                        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 ? <p id="error" className="error">{this.state.reply}</p> : null }
                                { this.state.showSuccess ? <p id="success" className="success">Thank you, we will be in touch asap.</p> : null }
                                <Button id="submit" variant="primary" type="submit">
                                    Submit
                                </Button>
                            </Form>
                        </Col>
                    </Row>
                </Container>
            </section>
        )
    }
}

export default Contact


期望的行为

我正在使用react-google-recaptchahttps://www.npmjs.com/package/react-google-recaptcha)进行 Recaptcha 验证,并在提交按钮的顶部插入了组件:

<ReCAPTCHA
    className="g-recaptcha"
    sitekey="XXXXXXXXXXXXXXXXXXXXX"
    onChange={this.onChange}
    theme="dark"
/>

onChange 函数应该设置state.verfied == true

onChange = (value) => {
    console.log("Captcha value:", value);
    this.setState({
        verified: true
    })
};

因此,handledSubmit()如果 reCaptcha 完成并且表单在没有重新加载页面的情况下提交,则这部分会触发:

if (this.state.verified) {
    fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
    })
    .then(this.handleSuccess)
    .catch(error => alert(error))
    event.preventDefault()
}

否则它应该呈现this.state.reply: "Please verify the ReCaptcha."在提交按钮上方。


它做了什么

提交按钮无需完成 reCaptcha 即可工作并提交表单。它将页面重新加载到http://localhost:8000/?name=Test&email=test&company=test&content=test&g-recaptcha-response=

我知道我使用状态的解决方法可能不是使用此模块的正确方法,但react-google-recaptcha文档没有提示如何正确地将验证与 reCaptcha API 集成。

很高兴对此提供任何支持。谢谢!

4

1 回答 1

0

我需要更改 onChange 函数来存储 reCaptchaResponse,如下所示:

onChange = (result) => {

    this.setState({
        verified: true,
        reCaptchaResponse: result,
    }) 
};

其次,我更新了 handleSubmit 中的条件以更早地检查验证,并将 reCaptchaResponse 集成到有效负载中,如下所示:

handleSubmit = event => {
    
    if (this.state.verified) {
        const url = 'https://xxxxxxxxxx.execute-api.eu-central-1.amazonaws.com/dev/email/send';

        this.setState({
            submitting: true
        })
        
        const payload = {
            name: this.state.name,
            email: this.state.email,
            company: this.state.company,
            content: this.state.content,
            result: this.state.reCaptchaResponse
        }

        fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(payload),
        })
        .then(this.handleSuccess)
        .catch(error => alert(error))
        event.preventDefault()
    } else {
        this.setState({
            reply: "Please verify the ReCaptcha"
        })
    }
}
于 2020-09-12T12:59:11.030 回答