7

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?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Kristof Rado
  • 713
  • 1
  • 8
  • 19
  • 1
    have you tried ``reset({...defaultValues})``? – Jeet Viramgama Jan 11 '22 at 09:33
  • After setting values with `setValue` or how? – Kristof Rado Jan 11 '22 at 09:35
  • 1
    no, you don't have to use ``setValue`` in order to set the ``defaultValue``. Make an object of ``defaultValue`` in ``useEffect``. Define all the neccasory fields like in your case ``name``. Do something like ``defaultValue.name = 'Kristof'`` and at last do ``reset({...defaultVales})``. Also checkout `reset`` for more clarification. https://react-hook-form.com/api/useform/reset – Jeet Viramgama Jan 11 '22 at 10:07
  • Here's the code sandbox link I've created. https://codesandbox.io/embed/hardcore-mclean-lbjdd?fontsize=14&hidenavigation=1&theme=dark – Jeet Viramgama Jan 11 '22 at 10:14
  • Yes, you were right! It is much simpler and also easier to reset the form with reset and not use setValue at all! Thanks for your help! Maybe if you can make this comment an answer, I can accept that. – Kristof Rado Jan 11 '22 at 10:23
  • Glad I could help you out. I've posted an answer to your question. Check it out and let me know if it requires any edits. Happy coding. – Jeet Viramgama Jan 11 '22 at 13:22

2 Answers2

17

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" />

Jeet Viramgama
  • 608
  • 5
  • 16
  • Thanks! The only missing piece in the docs was the difference between `setValue` and `reset`. However if you pre-fill a form I would now suggest for everyone to use `reset`. That way you can update all fields with one call (setValue can update 1 field) and also the `dirtyFields` and `isDirty` will work correctly. – Kristof Rado Jan 11 '22 at 13:40
  • 1
    Thank you! reset did the trick for me, I was trying to initialize the form values inside useFocusEffect but when running validation it was always empty, doing reset did the trick with the pre-fill – Goca Jun 23 '22 at 19:54
  • Be sure not to reset with null or undefined values because it might reset to the previous default value instead of the new one. – IcyIcicle Aug 26 '22 at 23:09
  • 1
    doesn't look like a crutch? – HackerMF Oct 24 '22 at 20:54
0

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.