667c374e68800110f648
·3 min read

React-Hook-Form: Submit a Form from Anywhere in Your Code

react
typescript
react-hook-form
zod
4d5fd787ac74e0caa4f7

Sohan R. Emon

Developer, Learner, Tech Enthusiast

A common issue faced by developers using React-Hook-Form is submitting a form from a button that is located outside the form element. Let's explore some solutions to tackle this challenge effectively.

The Problem

Imagine you have a form component that you want to submit using a button outside the form element. This can be tricky because React-Hook-Form expects the form submission to occur within the form element. So, how do we work around this?

tsx
<form
  id="editor-form"
  onSubmit={form.handleSubmit(onSubmit)}
  className="space-y-5 py-3"
  noValidate
>
  <InputWrapper name="title">
    <EditorInput />
  </InputWrapper>
  <FeaturesInputArray />
  <InputWrapper label="Backend Search Terms" name="backendFeatures">
    <EditorInput />
  </InputWrapper>
  <DescriptionInput />
  <button hidden id="editor-form--button" />
</form>

Solution 1: Using useFormContext

One straightforward solution is to use the useFormContext hook. Here's how you can do it:

jsx
import { useFormContext } from 'react-hook-form';

function CustomSubmitButton() {
  const { handleSubmit } = useFormContext();

  return (
    <>
      <button onClick={handleSubmit(console.log)}>Submit</button>
      <button onClick={() => handleSubmit(console.log)()}>Submit</button>
      {/* Ensure to call the curried function */}
    </>
  );
}

Solution 2: Triggering a Hidden Submit Button Programmatically

A simple solution is to programmatically trigger a hidden submit button within the form component.

Add a hidden button to the form component:

tsx
<form>
  {/* ... */}
  <button hidden id="editor-form--button" />
</form>

Then, trigger the button click programmatically:

jsx
const submit = () => document.getElementById('editor-form--button')?.click();

function CustomSubmitButton() {
  return (
    <button onClick={submit}>Submit</button>
  );
}

This allows you to submit the form from anywhere in your application.

Solution 3: Programmatic Form Submission

If you don't have access to the handleSubmit method, you can submit the form programmatically by referencing the form DOM element and dispatching a cancelable event. Here's how you can achieve this:

tsx
<form
  id="editor-form"
  ref={formRef}
  onSubmit={form.handleSubmit(onSubmit)}
>
  {/* ... */}
</form>

Ensure to add onSubmit to the form tag.

jsx
function CustomSubmitButton() {
  const submitWithRef = () => {
    formRef.current.dispatchEvent(new Event('submit', { cancelable: true }));
  };

  const submitWithoutRef = () => {
    document
      .getElementById('editor-form')
      ?.dispatchEvent(new Event('submit', { cancelable: true }));
  };

  return (
    <>
      <button onClick={submitWithRef}>Submit</button>
      <button onClick={submitWithoutRef}>Submit</button>
    </>
  );
}

Solution 4: Using the HTML form Attribute

You can resolve this issue by using the HTML form attribute to link the button to the form:

tsx
<form
  id="editor-form"
  onSubmit={form.handleSubmit(onSubmit)}
>
  {/* ... */}
</form>

Ensure to add onSubmit to the form tag.

jsx
function CustomSubmitButton() {
  return (
    <button type="submit" form="editor-form">Submit</button>
  );
}

This allows you to submit the form from anywhere in your application.

Conclusion

These solutions provide different methods to submit a form from outside the form element in React-Hook-Form. Depending on your specific use case, you can choose the one that best fits your needs. Remember, the React-Hook-Form community is always here to help, so don't hesitate to reach out if you have more questions or need further assistance.

Found this useful?