Today I Learned

hashrocket A Hashrocket project

React `useImperativeHandle` hook

I end up using useImperativeHandle hook to extract a component to be reusable. In this case I am using react-google-recaptcha lib for captcha and I have to pass a ref so the lib can bind some functions to that. Let's see how I got to expose a function to the parent component via ref:

import React, {useRef, useImperativeHandle, forwardRef} from 'react';
import ReCAPTCHA from 'react-google-recaptcha';

const Captcha = (_props, ref) => {
  const captchaRef = useRef();

  useImperativeHandle(ref, () => ({
    executeAsync: () => {
      captchaRef.current.executeAsync();
    },
  }));

  return (
    <ReCAPTCHA ref={captchaRef} sitekey="some key here" />
  );
};

export default forwardRef(Captcha);

I had to use both useImperativeHandle and forwardRef in order to receive the ref from the parent and "forward" to the ref internal to this component.

And here's how I am calling that:

const MyForm = () => {
  const captchaRef = useRef();

  const onSubmit = async (values) => {
    const recaptchaToken = await captchaRef.current?.executeAsync();
    placeOrder({recaptchaToken, ...values});
  };

  ...

  return (
    <form onSubmit={onSubmit}>
      ...
      <Captcha ref={captchaRef} />
      <input type="submit" value="Save" />
    </form>
  );
};

Although this is a very unusual thing to do in React, it was necessary in order to extract this component.

See More #react TILs
Looking for help? At Hashrocket, our JavaScript experts launch scalable, performant apps on the Web, Android and iOS. Contact us and find out how we can help you.