reaptcha
reaptcha copied to clipboard
getResponse returns an empty string
I am trying to utilize the getResponse API. In a real world scenario, I want to submit a Formik form. In the submit handler I want to first challenge the user and when ready, continue with the rest of the submission - an API call to the backend containing the token. This approach does not work, as setFieldValue and submit are called in the same render cycle and submit still has the old state at the moment of execution.
I have created a codesandbox isolating the issue: https://codesandbox.io/s/reaptcha-getresponse-returns-empty-string-zj4754?file=/src/App.tsx
A workaround is to use a ref to store the token value:
const SomeForm: React.FC = () => {
const captchaRef = useRef<Reaptcha>(null);
const tokenRef = useRef<string>('');
return (
<Formik
initialValues={{ ... }}
onSubmit={async (values) => {
const token = tokenRef.current;
// Continue with your form submission
}}
>
{({ setSubmitting, submitForm }) => (
<Form>
// Form content, fields, etc,
<Reaptcha
sitekey={''}
ref={captchaRef}
size="invisible"
onVerify={token => {
tokenRef.current = token;
submitForm();
}}
/>
<Button
type="submit"
onClick={() => {
captchaRef.current?.execute();
setSubmitting(true);
}}
>Submit</Button>
</Form>
)}
</Formik>
);
}
But I don't see this as very clean
Hey @nikolakov! Thanks for the reproduction on codesandbox - it helps a lot 😃
The problem here is that execute is based on Promise just for the sake of consistency through the whole API - it doesn't wait for anything but just call Recaptcha and resolve. I guess it would useful (and probably doable 🤔) to make execute actually resolve with the token already - but that's something we'd need to add.
For now, unfortunately I don't have any other solution. And the feature I just described will probably not be done (at least by me) in the nearest future 😢