[英]How to Integrate Google reCAPTCHA with react-hook-form?
我之前一直在使用react-hook-form,讓用戶以基本形式提交他們的email地址:
之前:react-hook-form,沒有 catpcha
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,但我很難理解如何將它集成到 react-hoook-form 中?
現在: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
function 內提交。在那里,我無法再訪問 email 的 react-hook-form 值。 我怎樣才能在那里獲得訪問權限?
另外:我的handleSubmit
function 現在是同步的,所以我不能等待 API 響應? 我怎樣才能使這個異步,但仍然可以使用react-hook-form
和recaptcha
? 有什么建議嗎?
useForm
提供了一個getValues()
function 來獲取表單的值。 您可以在組件內部的任何位置使用它。 這是參考: 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',
},
})
}
....
}
或者,您可以使用executeAsync
而不是在鈎子表單的onSubmit
中execute
,然后執行您的請求。
const onSubmit = ({ email }) => {
const token = await recaptchaRef.current.executeAsync();
// You API call here
}
您可以通過調用handleSubmit返回的 function 來使用您需要的數據調用您的真實onSubmit
handleSubmit
:
// inside your reCAPTCHA response function
const onSubmitWithFormValues = handleSubmit(
// binding form values to your function and any other params (e.g. token)
(...formSubmitParams) => onSubmit(...formSubmitParams, recaptchaToken)
)
onSubmitWithFormValues()
對於上面的示例, onSubmit
簽名如下:
const onSubmit = ({ email, password, username }, _ /* unused event */, recaptchaToken: string) => { ... }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.