Fantastic Forms with React Hook Forms
Tags: reachookform, validation, form, beginners
Published: 2023-07-21 10:37:53

With forms being a focal point of many applications, the ability to move swiftly in implementation is crucial as well as reusability and modular components. React Hook forms is here to cover those bases and more in the advancement in the space.

I'll start with why it's different and I'll give you a few stats as reference then I'll show you off some of the key basic features. I'll be using Formik as the leading comparison. 

Like Formik, React Hook Form is a form builder library that aims to reduce the pain of creating forms with React. A big difference between the two is that React Hook Form is designed to make use of uncontrolled components to avoid unnecessary re-rendering caused by user inputs.

This makes for significantly less re-renders on the form as you aren't rendering on every keystroke. React Hook Form isolates input components from the rest, preventing the whole form to re-render for a single field change.

Other libraries, including Formik, rely on form updates to cascade changes to the inputs, and although it has some advantages in terms of flexibility, this has a huge cost on performance

Installation

```
npm install react-hook-form
```
API References

The useForm API: this is one of those functions which you will be calling first before you apply any handling logic to your existing forms. It takes some optional arguments like mode, defaultValues, shouldFocusError, etc.

```
const { register } = useForm({
  mode: 'onSubmit',
  reValidateMode: 'onChange',
  defaultValues: {},
  resolver: undefined,
  context: undefined,
  shouldFocusError: true,
  shouldUnregister: true,
})
```
As for its methods, take a look at how these are used:

**register:** allows you to register an input/select ref and apply validation rules into React Hook Form based on both HTML default and custom validations.
```
`<input name="test" ref={register} />

<input
  name="test"
  ref={
    register({
      required: true
    })
  }
/>
```

**errors:** it’s an object which contains form errors and error messages corresponding to each field.

```
const { errors } = useForm();

<input name="singleErrorInput" ref={register({ required: true })} />
{errors.singleErrorInput && "Your input is required"}
```
**handleSubmit:** it’s a function that will pass the form data when form validation is successful and can be invoked remotely as well.
```
const { register, handleSubmit } = useForm();
const onSubmit = (data, e) => console.log(data, e);
const onError = (errors, e) => console.log(errors, e);

<form onSubmit={handleSubmit(onSubmit, onError)}>
      <input name="firstName" ref={register} />
      <input name="lastName" ref={register} />
      <button type="submit">Submit</button>
 </form>
```
**setError:** allows you to manually set one or more errors.

const { setError, errors } = useForm();
```
<input 
  name="username"
  type="text"
  onChange={() => {
      setError("username", {
      type: "manual",
      message: "Dont Forget Your Username Should Be Cool!"
    });
  }}
  ref={register} />

  {errors.username && <p>{errors.username.message}</p>}
```
**The Controller API:** it’s a wrapper component that makes it easier to work with external components from other libraries and frameworks, specifically helpful Material UI.

```
<Controller
  control={control}
  name="test"
  render={(
    { onChange, onBlur, value, name, ref },
    { invalid, isTouched, isDirty }
  ) => (
    <Checkbox
      onBlur={onBlur}
      onChange={(e) => onChange(e.target.checked)}
      checked={value}
      inputRef={ref}
    />
  )}
/>
```


**Validation:** RHF in-line validation is quick and simple allowing for validation on data type, length, or even regex patterns

```
<input name="firstName" 
  ref={register({ required: true, maxLength: 20 })} />
<input name="lastName" 
  ref={register({ pattern: /^[A-Za-z]+$/i })} />
<input name="age" type="number" 
  ref={register({ min: 18, max: 99 })} />
```

Combining this simplicity into what can become very complication with MUI or any other design library, you can just insert the ref above into the TextField component of the library and you've got your instant front end validation with limited rendering and 0 dependencies.

And if you're used to using schema validation like Yup, its even easier to implement. 

{% embed https://codesandbox.io/embed/react-hook-form-validation-yup-mrv28?fontsize=14&hidenavigation=1&theme=dark %}

Toss is multi-error options (per field) and you've got amazing user forward forms.
{% embed https://codesandbox.io/embed/react-hook-form-errormessage-multiple-error-messages-cis2m?fontsize=14&hidenavigation=1&theme=dark %}