如何将Google reCAPTCHA与Reaction-Hook-Form集成?

44u64gxh  于 2022-09-21  发布在  Go
关注(0)|答案(1)|浏览(108)

我以前一直在使用Reaction-Hook-Form,让用户以基本的形式提交他们的电子邮件地址:

之前:Reaction-Hook-Form,无CAPTCHA

import React from 'react'
import { useForm } from 'react-hook-form'
import { useRouter } from 'next/router'

const MyForm = ({ btnText = 'Join' }) => {
  const router = useRouter()

  const {
    register,
    handleSubmit,
    formState: { isSubmitted, isSubmitting, isValid, errors },
    reset,
  } = useForm({
    mode: 'onChange',
    reValidateMode: 'onChange',
  })

  const onSubmit = async ({ email }) => {

    const response = await fetch('/api/my-endpoint', {
        method: 'POST',
        body: JSON.stringify({
          email: email,
          captcha: captchaCode,
        }),
        headers: {
          'Content-Type': 'application/json',
        },
      })
  }

  return (
    <div tw="">
      <form
        onSubmit={handleSubmit(onSubmit)}
      >

        <input
          {...register('email', {
            required: 'We need an e-mail address',
          })}
          type="email"
        />

        <button
          type="submit"
        >
          Submit
        </button>
      </form>
    </div>
  )
}

export default MyForm

现在我刚刚添加了Google ReCaptcha v2,但我很难理解如何将其集成到Reaction-Hoook-Form中?

NOW:REACT-HOOK-FORM+Google recatpcha v2

import React from 'react'
import { useForm } from 'react-hook-form'
import ReCAPTCHA from 'react-google-recaptcha'

const MyForm = ({ btnText = 'Join' }) => {

  const {
    register,
    handleSubmit,
    formState: { isSubmitted, isSubmitting, isValid, errors },
    reset,
  } = useForm({
    mode: 'onChange',
    reValidateMode: 'onChange',
  })

  const onSubmit = ({ email }) => {
    // Execute the reCAPTCHA when the form is submitted
    recaptchaRef.current.execute()
  }

  const onReCAPTCHAChange = async captchaCode => {
    // If the reCAPTCHA code is null or undefined indicating that
    // the reCAPTCHA was expired then return early
    if (!captchaCode) {
      return
    }
    try {
      const response = await fetch('/api/my-endpoint', {
        method: 'POST',
        body: JSON.stringify({
          email: email,
          captcha: captchaCode,
        }),
        headers: {
          'Content-Type': 'application/json',
        },
      })
      if (response.ok) {
        // If the response is ok than show the success alert
        alert('Email registered successfully')
      } else {
        // Else throw an error with the message returned
        // from the API
        const error = await response.json()
        throw new Error(error.message)
      }
    } catch (error) {
      alert(error?.message || 'Something went wrong')
    } finally {
      // Reset the reCAPTCHA when the request has failed or succeeeded
      // so that it can be executed again if user submits another email.
      recaptchaRef.current.reset()

      reset()
    }
  }

  return (
      <form
        onSubmit={handleSubmit(onSubmit)}
      >
        <ReCAPTCHA
          ref={recaptchaRef}
          size="invisible"
          sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
          onChange={onReCAPTCHAChange}
        />
        <input
          {...register('email', {
            required: 'We need an e-mail address',
          })}
          type="email"
        />

        <button
          type="submit"
        >
         Submit
        </button>
      </form>
  )
}

export default MyForm

我的问题:

我似乎在苦苦挣扎的是,在我使用异步HandleSubmit调用之前:

const onSubmit = async ({ email }) => {

    const response = await fetch('/api/my-endpoint', {
        method: 'POST',
        body: JSON.stringify({
          email: email,
          captcha: captchaCode,
        }),
        headers: {
          'Content-Type': 'application/json',
        },
      })
  }

而现在,onSubmit仅激活验证码:

const onSubmit = ({ email }) => {
    // Execute the reCAPTCHA when the form is submitted
    recaptchaRef.current.execute()
  }

...而我的实际请求现在只在onReCAPTCHAChange函数中提交。在那里,我不再有权访问电子邮件的React挂钩形式的价值。我怎样才能在那里获得访问权限?

另外:我的handleSubmit函数现在是同步的,所以我不能等待API响应?我如何才能使这种情况不同步,同时仍能与react-hook-formrecaptcha一起工作?有什么建议吗?

anauzrmj

anauzrmj1#

useForm提供了一个getValues()函数来获取表单的值。您可以在组件内的任何位置使用它。参考资料如下:https://react-hook-form.com/api/useform/getvalues

const { getValues } = useForm()
 const onReCAPTCHAChange = async captchaCode => {
    // If the reCAPTCHA code is null or undefined indicating that
    // the reCAPTCHA was expired then return early
    if (!captchaCode) {
      return
    }
    try {
      const values = getValues()
      const response = await fetch('/api/my-endpoint', {
        method: 'POST',
        body: JSON.stringify({
          email: values.email,
          captcha: captchaCode,
        }),
        headers: {
          'Content-Type': 'application/json',
        },
      })

    }
    ....
}

或者,您可以在挂钩表单的onSubmit中使用executeAsync而不是execute,然后执行您的请求。

const onSubmit = ({ email }) => {
    const token = await recaptchaRef.current.executeAsync();

    // You API call here
}

相关问题