skip to Main Content

I’m using react-hook-form in my React project and I need to perform some actions when the form is reset.
However, I can’t find a way to listen to the form’s reset event and since I’m inside the child I don’t have direct access to the reset button event.

In this case I wanted to reset the check state that is not in the values to submit
Here is a simplified version of my form setup:

import { useState } from 'react';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';

const initialValues = { firstName: "empty", lastName: "empty" };
function MyForm() {
    const methods = useForm({ defaultValues: { ...initialValues } });

    const onSubmit = data => {
        console.log(data);
    };

    return (
        <FormProvider {...methods}>
            <CustomContent />
            <button type="button" onClick={methods.handleSubmit(onSubmit)}>Submit</button>
            <button type="button" onClick={() => methods.reset({ ...initialValues })}>Reset</button>
        </FormProvider >
    );
}

function CustomContent() {
    const { register } = useFormContext();

    const [isChecked, setIsChecked] = useState(false);

    return (
        <div>
            <input {...register('firstName')} placeholder="First Name" />

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

            <label >
                <input type="checkbox" checked={isChecked} onChange={() => setIsChecked((prev) => !prev)} />

                <span>Check me</span>
            </label>
        </div>
    );
}

export default MyForm;

Is there an event, callback, or hook in react-hook-form that allows me to listen specifically to the form reset action so that I can perform additional tasks (like resetting other states or triggering side effects or changing fields not saved in the form)?

I tried the solution proposed here Is there a way to listen to a form reset? – React Hook Form.

useEffect(() => {
        if (isFirstRender.current) {
            isFirstRender.current = false;
            return;
        }
        if (!isSubmitted && !isDirty) {
            setIsChecked(false);
        }
    }, [isDirty]);

But it didn’t work because it only works if you change a field that has been registered and it doesn’t work for this case.

Any guidance or suggestions would be appreciated. Thank you!

2

Answers


  1. You can use useEffect to watch for changes in the form’s state, specifically the reset effect. This works for either checks for form data is dirty or by monitoring the value changes.

    Here’s how you can set it up:

    function CustomContent() {
        const { register, reset, watch } = useFormContext();
        const [isChecked, setIsChecked] = useState(false);
        const watchedValues = watch();     // Watcher for changes in the form data
        useEffect(() => {
            if (Object.keys(watchedValues).length === 0) {
                setIsChecked(false); // Form got reset
            }
        }, [watchedValues]);
    
        return (
            <div>
                <input {...register('firstName')} placeholder="First Name" />
                <input {...register('lastName')} placeholder="Last Name" />
                <label>
                    <input
                        type="checkbox"
                        checked={isChecked}
                        onChange={() => setIsChecked((prev) => !prev)}
                    />
                    <span>Check me</span>
                </label>
            </div>
        );
    }
    Login or Signup to reply.
  2. In this case, you can use the onclick function with button type ‘reset’ or use the form’s onReset prop. Like this,

    function MyForm() {
    const methods = useForm({ defaultValues: { ...initialValues } });
    
    const onSubmit = data => {
        console.log(data);
    };
    
    return (
       <FormProvider {...methods}>
        <form onReset={() => console.log("triggered when reset")} onSubmit={methods.handleSubmit(onSubmit)}>
          <CustomContent />
          <button
            type="button"
            onClick={methods.handleSubmit(onSubmit)}
          >
            Submit
          </button>
          <button
            type="reset"
            onClick={() =>
              console.log("triggered when reset")
            }
          >
            Reset
          </button>
        </form>
      </FormProvider>
    
    );}
    

    I hope this will help you.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search