Skip to content

setValue

Update input value

setValue: (name: string, value: unknown, config?: Object) => void

This function allows you to dynamically set the value of a registered field. At the same time, it tries to avoid unnecessary re-rerenders.

Rules

  • Only the following conditions will trigger a re-render:

    • When an error is triggered by a value update

    • When an error is corrected by a value update

    • When setValue is invoked for the first time and formState.isDirty is set to true

  • You can also set the shouldValidate parameter to true in order to trigger a field validation.

    setValue('name', 'value', { shouldValidate: true })
  • You can also set the shouldDirty parameter to true in order to set field to dirty.

    setValue('name', 'value', { shouldDirty: true })
  • It's recommended to target the field's name rather than make the second argument a nested object.

    setValue('yourDetails.firstName', 'value'); // ✅ performant
    setValue('yourDetails', { firstName: 'value' }); // less performant 
  • It's recommended to register the input's name before invoking setValue. However, the following usages are still permitted.

    To update the entire Field Array, make sure the useFieldArray hook is being executed.

    // you can update an entire Field Array, 
    // this will trigger an entire field array to be remount and refreshed with updated values.
    setValue('fieldArray', [{ test: '1' }, { test: '2' }]); // ✅
    
    // you can setValue to a unregistered input
    setValue('notRegisteredInput', 'value'); // ✅ prefer to be registered
    
    // the following will register a single input (without register) 
    // and update its value in case you expected to be two inputs
    setValue('notRegisteredInput', { test: '1', test2: '2' }); // 🤔
    
    // with registered inputs, the setValue will update both inputs correctly.
    register('notRegisteredInput.test', '1')
    register('notRegisteredInput.test2', '2')
    setValue('notRegisteredInput', { test: '1', test2: '2' }); // ✅
    

Props

NameTypeDescription
namestring
  • Target a single input by its name.

  • Target a field array name. Note it will update both the fields object and the entire field array's internal state.

valueunknown

The value for the field. Make sure you supply the entire array when you update useFieldArray.

configshouldValidatebooleanWhether or not trigger validation while setting the input's value.
shouldDirtybooleanWhether to set the input itself to dirty.
shouldTouchbooleanWhether to set the input itself to be touched.
CodeSandbox
import * as React from "react";
import { useForm } from "react-hook-form";

const App = () => {
  const { register, handleSubmit, setValue } = useForm();

  const onSubmit = data => {
    console.log(data)
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <input {...register("lastName")} />
      <button onClick={() => setValue("firstName", "Bill")}>
        Set First Name Value
      </button>
      <button
        onClick={() =>
          setValue("lastName", "Luo", {
            shouldValidate: true,
            shouldDirty: true
          })
        }
      >
        Set Last Name
      </button>
      <input type="submit" />
    </form>
  );
};
import * as React from "react";
import { useForm } from "react-hook-form";

type FormInputs = {
  firstName: string
  lastName: string
}

const App = () => {
  const { register, handleSubmit, setValue } = useForm<FormInputs>();

  const onSubmit = (data: FormInputs) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName", { required: true })} />
      <input {...register("lastName", { required: true })} />
      <button onClick={() => setValue("firstName", "Bill")}>
        Set First Name Value
      </button>
      <button
        onClick={() =>
          setValue("lastName", "Luo", {
            shouldValidate: true,
            shouldDirty: true
          })
        }
      >
        Set Last Name
      </button>
      <input type="submit" />
    </form>
  );
};
import React from "react";
import { useForm } from "react-hook-form";

type FormValues = {
  string: string;
  number: number;
  object: {
    number: number;
    boolean: boolean;
  };
  array: {
    string: string;
    boolean: boolean;
  }[];
};

export default function App() {
  const { setValue } = useForm<FormValues>();
  
  setValue("string", "test");
  // function setValue<"string", string>(name: "string", value: string, shouldValidate?: boolean | undefined): void
  setValue("number", 1);
  // function setValue<"number", number>(name: "number", value: number, shouldValidate?: boolean | undefined): void
  setValue("number", "error");
  
  return <form />;
}
import React from "react";
import { useForm, useFieldArray } from "react-hook-form";

const ChildComponent = ({ index, control, register }) => {
  const { fields } = useFieldArray({
    name: `nest[${index}].nestedArray`,
    control
  });

  return (
    {fields.map((item, i) => (
      <input
        key={item.id}
        {...register(`nest[${index}].nestedArray[${i}].value`)}
        defaultValue={item.value}
      />
    ))}
  );
};

export default () => {
  const { register, control, setValue } = useForm({
    defaultValues: {
      nest: [
        { value: "1", nestedArray: [{ value: "2" }] },
        { value: "3", nestedArray: [{ value: "4" }] }
      ]
    }
  });
  const { fields } = useFieldArray({ name: "nest", control });

  React.useEffect(() => {
    setValue("nest", [
      {
        value: 0,
        nestedArray: [
          {
            value: 8
          }
        ]
      }
    ]);
  }, [setValue]);

  return (
    <>
      {fields.map((item, i) => (
        <div key={item.id}>
          <input
            {...register(`nest[${i}].value`)}
            defaultValue={item.value}
          />
          <ChildComponent control={control} register={register} index={i} />
        </div>
      ))}
    </>
  );
};
Edit