Kristof Rado
Kristof Rado

Reputation: 881

Set default values in React Hook Form

I want to check in a RHF if the user has modified the form values with the isDirty parameter.

Setting the defaultValues manually works:

const {handleSubmit, control, setValue, setError, setFocus} = useForm({defaultValues: {name: ""}});

This seem to work correctly.

But when the user tries to edit a form I load the values into the form with setValue.

Now I don't know how I can set programatically the defaultValues.

How to change React-Hook-Form defaultValue with useEffect()?

This is how I do, but the answer is not really correct. The values are set, but the defaultValues don't change this way so RHF can't compare.

Make sure to provide all inputs' defaultValues at the useForm, so hook form can have a single source of truth to compare whether the form is dirty.

https://react-hook-form.com/api/useform/formstate

How can I set the defaultValues dynamically so it even works in 'edit' mode?

Upvotes: 14

Views: 61872

Answers (4)

Kilian
Kilian

Reputation: 1939

If you want to set default values of individual fields you can also use the resetField method. Contrary to useing setValue you keep the intended behaviour from isDirty and future resets will properly restore these values.

This comes in handy if you have different parts of the form for whom data needs to be retrieved individually and asynchronously.

const { resetField } = useForm();

useEffect(() => {
   resetField('fieldId', {defaultValue:newDefaultValue});
},[newDefaultValue])

Upvotes: 0

othmane kahtal
othmane kahtal

Reputation: 151

I had the same issue! I was able to fix it by using the useEffect hook. Here's an example that worked for me:

  const { isLoaded, user } = useUser();

  const form = useForm<FormValues>({
    resolver: zodResolver(formSchema),
  });
  useEffect(() => {
    if (user?.firstName) form.setValue('first_name', user?.firstName);
    if (user?.lastName) form.setValue('last_name', user.lastName);
    if (user?.primaryPhoneNumber) form.setValue('phone', user.primaryPhoneNumber.phoneNumber);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user]);

Upvotes: 0

michalstruck
michalstruck

Reputation: 88

For future generations, remember to pass and set the value prop on you TextInput. I didn't do that and couldn't figure out why the value is set, but not displayed.

Upvotes: 1

Jeet
Jeet

Reputation: 795

It would be easier for you to use reset() to set the defaultValue of your form. Here's an example on CodeSandbox I have prepared for you.

All you have to do is to create an object inside useEffect(). Set your all default values using that object. At last spread that defaultValues object inside reset().

  useEffect(() => {
    let defaultValues = {};
    defaultValues.firstName = "Kristof";
    defaultValues.lastName = "Rado";
    reset({ ...defaultValues });
  }, []);

  <input {...register("firstName")} placeholder="First Name" />
  <input {...register("lastName")} placeholder="Last Name" />

Upvotes: 36

Related Questions