Reputation: 881
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
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
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
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
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