Reputation: 525
Basically what the title says. When I submit the form I'm checking if the login is successful, if not it displays a message. However, when the user starts to type I want this message to go away.
Kinda assumed isDirty
would be cleared once the form was submitted, but it remains dirty. I can call reset
from the onSubmit
, but that will clear the forms' content - which I don't want.
Ideas?
Upvotes: 34
Views: 46922
Reputation: 439
This worked for me:
const {
handleSubmit,
watch,
reset,
setValue,
getValues,
formState: { isValid },
} = methods;
reset(getValues(), { keepValues: true });
// or just
const submit = async (data: VitalsForm) => {
reset(data, { keepValues: true });
};
// which is the same
The reason I did this is because I have a very complicated form that uses watch()
to update some values.
Trying
reset({}, { keepValues: true });
// or
reset(undefined, { keepValues: true });
will make my useEffect()
run twice and make the form dirty again, because it has setValue()
inside it.
It seems like watch()
is triggered twice with 2 different values, one is the default/undefined (created by the {}
or the undefined
in the reset function) and the second is the real one. That makes my setValue()
change the value twice.
It seems like a very weird behavior that is native to react-hook-form
but I'm still looking into it.
Upvotes: 1
Reputation: 907
to set the current state as not dirty you should reset, send false to other params and send the current state as values:
reset(watch(), { keepValues: false, keepDirty: false, keepDefaultValues: false });
Upvotes: 4
Reputation: 21
To reset the isDirty
state without interfering with the form's values or default values, one example would be (being explicit):
reset(undefined, {keepValues: true, keepDirty: false, keepDefaultValues: false});
Example with React.useEffect()
hook:
I want to keep the submitted name
and filter
values and the ability to reset to the original defaultValues
, while resetting isDirty
:
const { reset, formState: { isSubmitSuccessful } } = useForm({
defaultValues: {
filter: "",
category: "",
}
});
React.useEffect(() => {
if(isSubmitSuccessful) {
reset(undefined, {keepValues: true, keepDirty: false, keepDefaultValues: false});
}
}, [isSubmitSuccessful, reset]);
The useForm Documentation explains under props the different options available for reset()
. They can also be referenced in the project's TypeScript Declaration
Infered type:
const reset: (values?: any, keepStateOptions?: Partial<{
keepDirtyValues: boolean;
keepErrors: boolean;
keepDirty: boolean;
keepValues: boolean;
keepDefaultValues: boolean;
keepIsSubmitted: boolean;
keepTouched: boolean;
keepIsValid: boolean;
keepSubmitCount: boolean;
}> | undefined) => void
Upvotes: 2
Reputation: 345
resetting in a useEffect() will work, but useEffect() should not be used for such things. see all the discussions around react 18 and useEffect() running twice.
just call
reset({}, { keepValues: true });
in your handleSubmit function at the end. no need to provide all values if you just want to keep the current ones.
Upvotes: 20
Reputation: 889
Thanks to this thread and posted by Charlie-Hua, we both solved this by: https://github.com/react-hook-form/react-hook-form/issues/3097
React.useEffect(() => {
if (isSubmitSuccessful) {
reset({}, { keepValues: true });
}
}, [isSubmitSuccessful, reset]);
Upvotes: 5
Reputation: 1187
You can send a new set of values to the reset. Since you do receive a set of values in the submit handler, you could connect both functionalities in the following way:
const {reset, handleSubmit, formState} = useForm();
const {isDirty} = formState;
const handleFormSubmit = (values) =>
{
//This would be the call where you post your info
fetch('google.com')
.then(response => console.log('response', response))
.finally(() => reset(values));
}
Notice the reset(values)
in the example above, which will reset your form to the values it tried to submit. Thus, rendering isDirty
back to false.
This is a rather common need in forms that do not reload or redirect after sending the information, so I assume they will eventually create a cleaner way to do it.
Upvotes: 53