forge42dev / remix-hook-form

Open source wrapper for react-hook-form aimed at Remix.run
MIT License
330 stars 27 forks source link

Form State isDirty not resetting after submit #62

Closed jseparovic closed 9 months ago

jseparovic commented 9 months ago

Hi,

I have a single route that is a simple instance update form. The form submits to itself and the action function then saves the changes to an API. It then returns the latest copy of the instance.

I'm using instance.updated from the API as a key into the form as this changes every time the instance is updated in the backend.

What is the best way to tell remix form that is should reload the default values so that the isDirty field goes back to false and hence the buttons go back to being disabled?

export default function InstanceView() {
    let instance: any = useLoaderData();

    const {
        handleSubmit,
        formState: { errors },
        register,
        control,
        reset,
    } = useRemixForm({
        mode: "onSubmit",
        resolver,
        defaultValues: {
            ...instance,
        },

    });

    const { isDirty} = useFormState({control});

    console.log({updated: instance.updated, isDirty});

    return (
        <div className="mx-4 my-4">
            <Form onSubmit={handleSubmit} key={instance.updated}>
                <CommonFormField
                    name={"name"}
                    label={"Name"}
                    description={"Name for the entry"}
                    register={register}
                    errors={errors}
                />
                <CommonFormField
                    name={"description"}
                    label={"Description"}
                    description={"User-defined descriptive text"}
                    inputType={CommonFormInputType.Textarea}
                    register={register}
                    errors={errors}
                />
                <div className={"flex"}>
                    <Button className="bg-red-500 w-[150px]" disabled={!isDirty} onClick={() => reset()}>
                        Cancel
                    </Button>
                    <Button className="ml-8 bg-green-500 w-[150px]" disabled={!isDirty}>
                        Save
                    </Button>
                </div>
            </Form>
        </div>
    )
}

Console output:

index.tsx:133 {updated: '2023-12-09T06:49:35.997Z', isDirty: true}
index.tsx:133 {updated: '2023-12-09T06:49:35.997Z', isDirty: true}
index.tsx:133 {updated: '2023-12-09T06:49:35.997Z', isDirty: true}
index.tsx:133 {updated: '2023-12-09T06:53:31.449Z', isDirty: true}
index.tsx:133 {updated: '2023-12-09T06:53:31.449Z', isDirty: true}
jseparovic commented 9 months ago

Just needed to reset the form state and pass in the new instance for resetting the default values:

    useEffect(() => {
        if(form) {
            form.reset(instance);
        }
    }, [instance])