Expose a function from a functional component - React

Viewed 1339

I have a functional component Form. I need to expose a function validate from it.

Validate will typically use state variables inside the form.

Now, I'm unable to think of a way to expose it such that whichever component uses form, it can simply validate form like below

 const { validateForm } = Form;
 const isFormValid = validateForm();

Provided my Form look like below

const Form = () => {
    const isError = () => {}
    const isEmpty = () => {}
    const validate = () => {
        return isError() || isEmpty();
    }
}

Is there a way to do it via hooks? I cannot just get my head around at this moment.

P.S - I completely understand it breaks the philosophy of declarative and is an imperative way but there are use cases where this is required. Esp. when people expose it via libraries. Ant design does that too - https://ant.design/components/form/

So I am completely fine with it.

1 Answers

Yes you can do it combining useRef and useImperativeHandle by doing the following:

  • Your Form must be forwarding ref using React.forwardRef.

const MyForm = React.forwardRef((props, ref) => {

  • Declare the form validation inside the form component by using the useImperativeHandle hook this way:
  React.useImperativeHandle(ref, () => ({
    validate: () => {
      alert("now, the form is validating");
    }
  }));
  • In the form's parent, create a ref and pass it to your form <MyForm ref={formRef} />

Then in your event just use formRef.current.validate();

Please find a demo in this codesandbox

Related