reset
Reset the form to its default values and clear state.
</> reset: UseFormReset
Reset the entire form state, fields reference, and subscriptions. There are optional arguments that allow partial form state reset.
Props
Reset has the ability to retain formState. Here are the options you may use:
| Name | Type | Description | |
|---|---|---|---|
values | object | (values: Object) => Object | An optional object to reset form values, and it's recommended to provide the entire defaultValues when supplied. Since v7.36.0 Also accepts a callback that receives the current form values and returns the next values. | |
options | keepErrors | boolean | All errors will remain. This behavior is not guaranteed after further user actions. |
keepDirty | boolean | DirtyFields form state will remain, and isDirty will temporarily remain as the current state until further user's action.Important: this keep option doesn't reflect form input values but only dirty fields form state. | |
keepDirtyValues | boolean | Since v7.31.0 DirtyFields and isDirty will remain, and only non-dirty fields will be updated to the newly provided values. Check out the example.Important: formState dirtyFields will need to be subscribed. | |
keepValues | boolean | Form input values will be unchanged. | |
keepDefaultValues | boolean | Keep the same defaultValues which are initialised via useForm.
| |
keepIsSubmitted | boolean | isSubmitted state will be unchanged. | |
keepIsSubmitSuccessful | boolean | Since v7.47.0 isSubmitSuccessful state will be unchanged. | |
keepTouched | boolean | isTouched state will be unchanged. | |
keepIsValidating | boolean | Since v7.51.0 isValidating/validatingFields state will be unchanged, rather than cleared by the reset. | |
keepIsValid | boolean | isValid will temporarily persist as the current state until additional user actions. | |
keepSubmitCount | boolean | submitCount state will be unchanged. | |
keepFieldsRef | boolean | Since v7.60.0 Preserve the internal field references (registered inputs). Useful when you want to reset form values without causing inputs to unmount and remount. |
RULES
- It is recommended to always provide
defaultValueswhen resetting a form to ensure all inputs, especially controlled components, are restored correctly. - Avoid calling
resetinsideonSubmit.handleSubmitupdatesisSubmitted,isSubmitSuccessfulandsubmitCountafter your handler finishes, so aresetthere clears the values but not the submission state. Reset in auseEffectwhenformState.isSubmitSuccessfulbecomestrueinstead (see the Submit with Reset example below). - Calling
resetwithvaluesupdates the form'sdefaultValuesunlessoptions.keepDefaultValuesis set. Ifresetis later called withoutvaluesor with{}, the form resets to the lastvaluesprovided instead of the initialdefaultValues.
Examples
Uncontrolled
import { useForm } from "react-hook-form"interface UseFormInputs {firstName: stringlastName: string}export default function Form() {const {register,handleSubmit,reset,formState: { errors },} = useForm<UseFormInputs>()const onSubmit = (data: UseFormInputs) => {console.log(data)}return (<form onSubmit={handleSubmit(onSubmit)}><label>First name</label><input {...register("firstName", { required: true })} /><label>Last name</label><input {...register("lastName")} /><input type="submit" /><input type="reset" value="Standard Reset Field Values" /><inputtype="button"onClick={() => reset()}value="Custom Reset Field Values & Errors"/></form>)}
import { useCallback, useEffect } from "react"import { useForm } from "react-hook-form"export default function App() {const { register, handleSubmit, reset } = useForm()const resetAsyncForm = useCallback(async () => {const response = await fetch("./api/formValues.json")const result = await response.json() // result: { firstName: 'test', lastName: 'test2' }reset(result) // asynchronously reset your form values}, [reset])useEffect(() => {resetAsyncForm()}, [resetAsyncForm])return (<form onSubmit={handleSubmit((data) => {})}><input {...register("firstName")} /><input {...register("lastName")} /><inputtype="button"onClick={() => {reset({firstName: "bill",},{keepErrors: true,keepDirty: true,})}}/><buttononClick={() => {reset((formValues) => ({...formValues,lastName: "test",}))}}>Reset partial</button></form>)}
Controller
import { useForm, Controller } from "react-hook-form"import { TextField } from "@mui/material"interface IFormInputs {firstName: stringlastName: string}export default function App() {const { register, handleSubmit, reset, setValue, control } =useForm<IFormInputs>()const onSubmit = (data: IFormInputs) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><Controllerrender={({ field }) => <TextField {...field} />}name="firstName"control={control}rules={{ required: true }}defaultValue=""/><Controllerrender={({ field }) => <TextField {...field} />}name="lastName"control={control}defaultValue=""/><input type="submit" /><input type="button" onClick={() => reset()} /><inputtype="button"onClick={() => {reset({firstName: "bill",lastName: "luo",})}}/></form>)}
import { useForm, Controller } from "react-hook-form"import { TextField } from "@mui/material"export default function App() {const { register, handleSubmit, reset, setValue, control } = useForm()const onSubmit = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><Controllerrender={({ field }) => <TextField {...field} />}name="firstName"control={control}rules={{ required: true }}defaultValue=""/><Controllerrender={({ field }) => <TextField {...field} />}name="lastName"control={control}defaultValue=""/><input type="submit" /><input type="button" onClick={() => reset()} /><inputtype="button"onClick={() => {reset({firstName: "bill",lastName: "luo",})}}/></form>)}
Submit with Reset
import { useEffect } from "react"import { useForm, useFieldArray, Controller } from "react-hook-form"function App() {const {register,handleSubmit,reset,formState,formState: { isSubmitSuccessful },} = useForm({ defaultValues: { something: "anything" } })const onSubmit = (data) => {// It's recommended to reset in useEffect as execution order matters// reset({ ...data })}useEffect(() => {if (formState.isSubmitSuccessful) {reset({ something: "" })}}, [formState.isSubmitSuccessful, reset])return (<form onSubmit={handleSubmit(onSubmit)}><input {...register("something")} /><input type="submit" /></form>)}
Field Array
import { useEffect } from "react"import { useForm, useFieldArray, Controller } from "react-hook-form"function App() {const { register, control, handleSubmit, reset } = useForm({defaultValues: {loadState: "unloaded",names: [{ firstName: "Bill", lastName: "Luo" }],},})const { fields, remove } = useFieldArray({control,name: "names",})useEffect(() => {reset({names: [{firstName: "Bob",lastName: "Actually",},{firstName: "Jane",lastName: "Actually",},],})}, [reset])const onSubmit = (data) => console.log("data", data)return (<form onSubmit={handleSubmit(onSubmit)}><ul>{fields.map((item, index) => (<li key={item.id}><input {...register(`names.${index}.firstName`)} /><Controllerrender={({ field }) => <input {...field} />}name={`names.${index}.lastName`}control={control}/><button type="button" onClick={() => remove(index)}>Delete</button></li>))}</ul><input type="submit" /></form>)}
Video
Tips
- For a "Discard changes" button, call
reset()with no arguments. The form goes back to the last default values. - After a successful save, call
reset(savedData)so the saved data becomes the new baseline andisDirtygoes back tofalse. If you only want to move the dirty baseline and keep errors, touched fields, and submission state, useresetDefaultValues. - When the server sends fresh data while the user is editing, use
reset(newData, { keepDirtyValues: true }). Fields the user changed keep their values, and the other fields are updated. - To load data once from an API, use
useForm({ values })instead ofresetin auseEffect. See which option to use.
Troubleshooting
reset() clears the form instead of going back to the loaded data
Why it happens
reset() with no arguments goes back to the default values. If you loaded the data with setValue, the default values never changed, so the form is reset to the original empty values.
Fix
Load the data with reset(data) or values. The loaded data then becomes the default values, and a later reset() returns to it.