[英]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.