# setValue

> Dynamically update a registered field's value with options to trigger validation, mark the field dirty, or set it as touched.

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

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

This function allows you to dynamically set the value of a <strong>registered</strong> field and provides options to validate and update the form state. At the same time, it attempts to avoid unnecessary re-renders.

### Props

---

| Name                                     |                                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`<br/> `string`   |                                                   | Target a single field or field array by name.                                                                                                                                                                                                                                                                                                                                                               |
| `value`<br/> `unknown` |                                                   | The value for the field. This argument is required and cannot be `undefined`.                                                                                                                                                                                                                                                                                                                               |
| `options`                                | `shouldValidate`<br/> `boolean` | <ul><li>Whether to compute if your input is valid or not (subscribed to `errors`).</li><li>Whether to compute if your entire form is valid or not (subscribed to `isValid`).</li><li>This option only recomputes validity for the specified field, not the entire form's `errors`.</li></ul>                                                                          |
|                                          | `shouldDirty`<br/> `boolean`    | <ul><li>Whether to compute if your input is dirty or not against your `defaultValues` (subscribed to `dirtyFields`).</li><li>Whether to compute if your entire form is dirty or not against your `defaultValues` (subscribed to `isDirty`).</li><li>This option will update `dirtyFields` at the specified field level, not the entire form's dirty fields.</li></ul> |
|                                          | `shouldTouch`<br/> `boolean`    | _(since v7.8.0)_ Whether to set the input itself to be touched.                                                                                                                                                                                                                                                                                                                                    |
|                                          | `delayError`<br/> `boolean`     | _(since v7.82.0)_ Opt-in flag that delays the display of the resulting validation error, using the delay (in milliseconds) configured via [`useForm({ delayError })`](https://react-hook-form.com/docs/useform#delayError). Only takes effect when `shouldValidate` is also set to `true`.                                                                                                                                    |

> **Important: Rules**
>
> - By default, `setValue` only updates the value and notifies [`watch`](https://react-hook-form.com/docs/useform/watch), [`useWatch`](https://react-hook-form.com/docs/usewatch) and [`subscribe`](https://react-hook-form.com/docs/useform/subscribe). It does **not** validate the field (even after the form has been submitted) or mark it as dirty or touched. Pass the options you need:
>
>   ```javascript
>   setValue("firstName", "Bill", {
>     shouldValidate: true, // update errors and isValid
>     shouldDirty: true, // update dirtyFields and isDirty
>     shouldTouch: true, // update touchedFields
>   })
>   ```
>
> - `shouldDirty` only guarantees that the target field is marked in `dirtyFields` immediately. Because `isDirty` always compares current values against `defaultValues`, a later update to _any_ field can trigger a `dirtyFields` recompute that also surfaces other fields whose value already differs from their default — including ones last written with `shouldDirty: false`.
>
> - You can use methods such as [replace](https://react-hook-form.com/docs/usefieldarray#return) or [update](https://react-hook-form.com/docs/usefieldarray#return) for a field array; however, they will cause the component to unmount and remount for the targeted field array.
>
>   ```javascript
>   const { update } = useFieldArray({ name: "array" })
> 
>   // unmount fields and remount with updated value
>   update(0, { test: "1", test1: "2" })
> 
>   // will directly update input value
>   setValue("array.0.test1", "1")
>   setValue("array.0.test2", "2")
>   ```
>
> - It's recommended to target the field's name rather than make the second argument a nested object.
>
>   ```javascript
>   setValue("yourDetails.firstName", "value") // ✅ performant
>   setValue("yourDetails", { firstName: "value" }) ❌ // less performant
> 
>   register("nestedValue", { value: { test: "data" } }) // register a nested value input
>   setValue("nestedValue.test", "updatedData") // ❌ failed to find the relevant field
>   setValue("nestedValue", { test: "updatedData" }) // ✅ setValue finds the input and updates it
>   ```
>
> - It's recommended to register the input's name before invoking `setValue`. To update the entire `FieldArray`, make sure the `useFieldArray` hook is being executed first.
>
>   **Important:** Prefer `replace` from `useFieldArray` for updating an entire field array — it's the more explicit, purpose-built API, and this `setValue` usage may become discouraged in a future version.
>
>   ```javascript
>   // you can update an entire Field Array,
>   setValue("fieldArray", [{ test: "1" }, { test: "2" }]) // ⚠️ works, but prefer replace() from useFieldArray
> 
>   // you can use `setValue` on an unregistered input
>   setValue("notRegisteredInput", "value") // ✅ prefer it to be registered
> 
>   // the following will implicitly register a single input (without register being invoked)
>   setValue("resultSingleNestedField", { test: "1", test2: "2" }) // ⚠️ works, but registers a field you never called register() on — prefer registering it explicitly
> 
>   // With registered inputs, `setValue` will update both inputs correctly.
>   register("notRegisteredInput.test")
>   register("notRegisteredInput.test2")
>   setValue("notRegisteredInput", { test: "1", test2: "2" }) // ✅ sugar syntax to setValue twice
>   ```
>

### Examples

---

**Basic**

[Open in CodeSandbox](https://codesandbox.io/s/react-hook-form-v7-ts-setvalue-8z9hx)

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

const App = () => {
  const { register, setValue } = useForm({
    defaultValues: {
      firstName: "",
    },
  })

  return (
    <form>
      <input {...register("firstName", { required: true })} />
      <button type="button" onClick={() => setValue("firstName", "Bill")}>
        setValue
      </button>
      <button
        type="button"
        onClick={() =>
          setValue("firstName", "Luo", {
            shouldValidate: true,
            shouldDirty: true,
          })
        }
      >
        setValue options
      </button>
    </form>
  )
}
```

**Delay Error**

```javascript
// the actual delay (in ms) is configured once at the form level
const { setValue } = useForm({ delayError: 500 })

setValue("firstName", "Bill", {
  delayError: true, // opt in to the 500ms delay configured above
  shouldValidate: true,
})
```

**Dependent Fields**

[Open in CodeSandbox](https://codesandbox.io/s/dependent-field-dwin1)

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

type FormValues = {
  a: string
  b: string
  c: string
}

export default function App() {
  const { watch, register, handleSubmit, setValue, formState } =
    useForm<FormValues>({
      defaultValues: {
        a: "",
        b: "",
        c: "",
      },
    })
  const onSubmit = (data: FormValues) => console.log(data)
  const [a, b] = watch(["a", "b"])

  useEffect(() => {
    if (formState.touchedFields.a && formState.touchedFields.b && a && b) {
      setValue("c", `${a} ${b}`)
    }
  }, [setValue, a, b, formState])

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("a")} placeholder="a" />
      <input {...register("b")} placeholder="b" />
      <input {...register("c")} placeholder="c" />
      <input type="submit" />

      <button
        type="button"
        onClick={() => {
          setValue("a", "what", { shouldTouch: true })
          setValue("b", "ever", { shouldTouch: true })
        }}
      >
        trigger value
      </button>
    </form>
  )
}
```

### Video

---

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

### Tips

---

- When a value comes from the user through a custom widget, such as a map picker or a rich-text editor, pass `{ shouldDirty: true, shouldTouch: true, shouldValidate: true }`. The field then behaves the same as a native input that the user typed in.
- To update several fields at once, use [`setValues`](https://react-hook-form.com/docs/useform/setvalues). It updates them with a single re-render, while calling `setValue` many times can cause more renders.
- Do not call `setValue` during render. Call it in an event handler or an effect.

### Troubleshooting

---

#### `isDirty` and errors don't change after `setValue`

**Why it happens:**

By default, `setValue` only updates the value. It does not validate the field or mark it as dirty or touched.

**Fix:**

Pass the options you need:

```javascript
setValue("email", value, {
  shouldValidate: true,
  shouldDirty: true,
  shouldTouch: true,
})
```
