javascriptreactjsgatsbynetlifyreact-google-recaptcha

"Uncaught (in promise): null" when lifting up the value of reCAPTCHA


I'm trying to lift up the value of the reCAPTCHA (with react-google-recaptcha) once the user clicks it. I can easily get the value but I can't send it to the parent component. It throws:

Uncaught (in promise): null

const RecaptchaInput = ({ name, isValid, errorMessage, onChange }) => {
  const recaptchaReference = useRef(null);

  const handleChange = () => {
    let recaptchaValue = recaptchaReference.current.getValue(); 
    console.log('recaptchaValue',recaptchaValue) //prompts the value

    onChange({ value: recaptchaValue, name: `recaptcha` });
  };

  return <div>
    <label htmlFor={name}>
      <Recaptcha sitekey={process.env.GATSBY_SITE_RECAPTCHA_KEY}
                 ref={recaptchaReference}
                 onChange={handleChange} />
    </label>
    {!isValid && <small>{errorMessage}</small>}
  </div>;
};

The value is properly prompted in the console but I can't send it onChange function. Neither a dummy object like {value: 'hello', name: 'recaptcha'}.

My onChange function destructures the arguments into name and value, that's why I lift up an object like this.

As far as I read it seems to be related to the callback of Google's Recaptcha but I can't figure out how to bypass it in Gatsby's/React application.


Solution

  • After hours of trial and error, I fixed it by making an async promise-based value fetching. For everyone that may be stuck in the similar issues:

    const RecaptchaInput = ({ name, isValid, errorMessage, onChange }) => {
      const recaptchaReference = useRef(null);
    
      const handleChange = async () => {
        let recaptchaValue = recaptchaReference.current.getValue(); 
        console.log('recaptchaValue',recaptchaValue) //prompts the value
    
        onChange({ value: recaptchaValue, name: `recaptcha` });
      };
    
      return <div>
        <label htmlFor={name}>
          <Recaptcha sitekey={process.env.GATSBY_SITE_RECAPTCHA_KEY}
                     ref={recaptchaReference}
                     onChange={handleChange} />
        </label>
        {!isValid && <small>{errorMessage}</small>}
      </div>;
    };