Today I Learned

A Hashrocket project

Ready to join Hashrocket? Find Openings here and apply today.

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.

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.