# unregister

> Remove a registered input from React Hook Form, optionally preserving its value, error, dirty, or touched state on unmount.

Source: https://react-hook-form.com/docs/useform/unregister

## `unregister:` [UseFormUnregister](https://react-hook-form.com/ts#UseFormUnregister)

This method allows you to `unregister` a single input or an array of inputs. It also provides a second optional argument _(since v7.0.0)_ to keep state after unregistering an input.

### Props

---

The example below shows what to expect when you invoke the `unregister` method.

```javascript
<input {...register('yourDetails.firstName')} />
<input {...register('yourDetails.lastName')} />
```

| Type                          | Input Name                             | Value               |
| ----------------------------- | -------------------------------------- | ------------------- |
| `string`   | `unregister("yourDetails")`            | `{}`                |
| `string`   | `unregister("yourDetails.firstName")`  | `{ lastName: '' }`  |
| `string[]` | `unregister(["yourDetails.lastName"])` | `{ firstName: '' }` |

### Options

---

| Name               | Type                         | Description                                                                                                                                                                                                                   |
| ------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `keepDirty`        | `boolean` | `isDirty` and `dirtyFields` will be remained during this action. However, this is not going to guarantee the next user input will not update `isDirty` formState, because `isDirty` is measured against the `defaultValues`.  |
| `keepTouched`      | `boolean` | `touchedFields` will no longer remove that input after unregister.                                                                                                                                                            |
| `keepIsValid`      | `boolean` | `isValid` will be remained during this action. However, this is not going to guarantee the next user input will not update `isValid` for schema validation, you will have to adjust the schema according with the unregister. |
| `keepError`        | `boolean` | `errors` will not be updated.                                                                                                                                                                                                 |
| `keepValue`        | `boolean` | input's current `value` will not be updated.                                                                                                                                                                                  |
| `keepDefaultValue` | `boolean` | input's `defaultValue` which defined in `useForm` will be remained. **Note:** only has an effect when the form's top-level `shouldUnregister` option is `false` (the default); it is a no-op when `shouldUnregister: true`.   |
| `keepIsValidating` | `boolean` | _(since v7.51.0)_ `validatingFields`/`isValidating` state for the unregistered field will be retained rather than cleared.                                                                                           |

> **Important: Rules**
>
> - This method will remove input reference and its value, which means **built-in validation** rules will be removed as well.
> - By `unregister` an input, it will not affect the schema validation.
>
>   ```javascript
>   const schema = yup
>     .object()
>     .shape({
>       firstName: yup.string().required(),
>     })
>     .required()
> 
>   unregister("firstName") // this will not remove the validation against firstName input
>   ```
>
> - Make sure you unmount that input which has `register` callback or else the input will get registered again.
>
>   ```javascript
>   const [show, setShow] = useState(true)
> 
>   const onClick = () => {
>     unregister("test")
>     setShow(false) // make sure to unmount that input so register not invoked again.
>   }
> 
>   {
>     show && <input {...register("test")} />
>   }
>   ```
>

### Examples

---

**TS**

```tsx
import { useEffect } from "react"
import { useForm } from "react-hook-form"

type FormInputs = {
  name: string
  addPhone: boolean
  phone?: string
}

export default function App() {
  const { register, handleSubmit, unregister, watch } = useForm<FormInputs>({
    defaultValues: { name: "", addPhone: false, phone: "" },
  })
  const addPhone = watch("addPhone")
  const onSubmit = (data: FormInputs) => console.log(data)

  useEffect(() => {
    // the phone input is already unmounted here, so the field stays removed
    if (!addPhone) unregister("phone")
  }, [addPhone, unregister])

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name")} placeholder="Name" />

      <label>
        <input type="checkbox" {...register("addPhone")} />
        Add a phone number
      </label>

      {addPhone && <input {...register("phone")} placeholder="Phone" />}

      <button type="submit">Submit</button>
    </form>
  )
}
```

**JS**

```javascript
import { useEffect } from "react"
import { useForm } from "react-hook-form"

export default function App() {
  const { register, handleSubmit, unregister, watch } = useForm({
    defaultValues: { name: "", addPhone: false, phone: "" },
  })
  const addPhone = watch("addPhone")
  const onSubmit = (data) => console.log(data)

  useEffect(() => {
    // the phone input is already unmounted here, so the field stays removed
    if (!addPhone) unregister("phone")
  }, [addPhone, unregister])

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name")} placeholder="Name" />

      <label>
        <input type="checkbox" {...register("addPhone")} />
        Add a phone number
      </label>

      {addPhone && <input {...register("phone")} placeholder="Phone" />}

      <button type="submit">Submit</button>
    </form>
  )
}
```

### Video

---

[Watch on YouTube](https://www.youtube.com/watch?v=TM99g_NW5Gk)

### Tips

---

- For fields that show and hide, try the `shouldUnregister: true` option (on [`useForm`](https://react-hook-form.com/docs/useform#shouldUnregister) or [`register`](https://react-hook-form.com/docs/useform/register#options)) before you call `unregister` by hand. The field is removed when its input unmounts.
- With a resolver, `unregister` does not change the schema. Make the schema conditional instead, for example with a discriminated union or `.optional()`, so hidden fields are not validated.

### Troubleshooting

---

#### The field comes back right after `unregister`

**Why it happens:**

The input is still rendered. On the next render, its `register` call registers the field again, with the value still in the input.

**Fix:**

Remove the input from the page first, then call `unregister`. Or use the `shouldUnregister: true` option, which unregisters the field automatically when its input unmounts.
