Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make react-hook-form work with multiple forms in one page?

I am using react-hook-form in my project and I have 2 totally separate forms, but when I submit one of the forms and if some fields in the other form is required I can't submit the current form, check the demo, and try to submit one of the form, the forms should work independently of each other but it looks like they depend on each other.

any help please?

like image 626
webcoder Avatar asked Feb 18 '20 08:02

webcoder


People also ask

Which is better Formik or React Hook form?

React Hook Form isolates input components from the others and prevents re-render of the form for a single input. It avoids this unnecessary re-rendering. So it is a great advantage in terms of the performance compared to Formik which updates every change in every input field.

Is React Hook form uncontrolled?

React Hook Form relies on uncontrolled form, which is the reason why the register function capture ref and controlled component has its re-rendering scope with Controller or useController .


2 Answers

Welcome to StackOverflow @webcoder You are using the same hook instance for both forms. You will have to reuse with different names.

import React from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

import "./styles.css";

function App() {
  const {
    register,
    formState: { errors },
    handleSubmit,
  } = useForm({
    mode: "onBlur",
  });

  const {
    register: register2,
    formState: { errors: errors2 },
    handleSubmit: handleSubmit2,
  } = useForm({
    mode: "onBlur",
  });

  const onSubmit = (data) => {
    alert(JSON.stringify(data));
  };

  const onSubmitEmail = (data) => {
    alert(JSON.stringify(data));
  };

  return (
    <div className="App">
      <form key={1} onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label htmlFor="firstName">First Name</label>
          <input
            name="firstName"
            placeholder="bill"
            ref={register({ required: true })}
          />
          {errors.firstName && <p>This is required</p>}
        </div>

        <div>
          <label htmlFor="lastName">Last Name</label>
          <input
            name="lastName"
            placeholder="luo"
            ref={register({ required: true })}
          />
          {errors.lastName && <p>This is required</p>}
        </div>
        <input type="submit" />
      </form>

      <form key={2} onSubmit={handleSubmit2(onSubmitEmail)}>
        <div>
          <label htmlFor="email" placeholder="[email protected]">
            Email
          </label>
          <input name="email" ref={register2({ required: true })} />
          {errors2.email && <p>This is required</p>}
        </div>
        <input type="submit" />
      </form>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
like image 141
Faizaan Khan Avatar answered Oct 11 '22 01:10

Faizaan Khan


Quick update to Faizaan's answer: in my case, errors should be used with formState, not by itself. Therefore, the property should be imported as:

const { formState: { errors } } = useForm();
const { formState: { errors: errors2 } } = useForm();

The names might be confusing, but these is the solution that I arrived at.

like image 9
crimsonpython24 Avatar answered Oct 11 '22 01:10

crimsonpython24