gene b.
gene b.

Reputation: 11994

Disabling Submit button on click with useRef (to prevent double clicks) inside a Formik form causes Formik submission to break

I have a Formik form as below, and it works OK in its original implementation. One extra feature I had to add is that when the Submit button is clicked, I have to disable it, to prevent double-clicks. I followed the example here which is to define a ref={submitBtnRef} on a button. But after inserting this code in the onClick, Formik doesn't submit anymore, it just stops. If I remove this new code everything works. There are no validation errors; I output Formik's errors and it's empty. Also no console errors.

const submitForm = async (formValues) => {
    const url = '/app/submitAgreement';
    let obj = {'formValues': formValues};
    await axios.post(url, obj);
}

// Define a Submit Button Ref for disabling in Submit's onClick() below
let submitBtnRef = useRef();

<Formik 
    enableReinitialize
    validationSchema={mySchema} 
    onSubmit={ (values) => {
        submitForm(values); // Calls submitForm() function if there are no errors
    }}
    initialValues={initialFormValues}
>
    {
        ({handleSubmit, handleChange, handleBlur, setFieldValue, setFieldTouched, values, touched, isValid, errors}) 
        => (

            <Form onSubmit={handleSubmit}> {/* Form starts here */}
            ..
            ..
            <Button type="submit" ref={submitBtnRef}
                    onClick={() => { 
                       // If I remove this Ref-Disable code it works, but I need to disable Submit
                       if(submitBtnRef.current) {
                          submitBtnRef.current.setAttribute("disabled", "disabled");
                       }
            
                       // The default form-submit method specified in the Formik Form, submitForm(),
                       // will now be executed if there are no validation errors
                       }} 
    >Submit</Button>                
    ..
    </Form>

Upvotes: 1

Views: 1981

Answers (1)

Ro Milton
Ro Milton

Reputation: 2536

Don't manipulate the DOM directly. The link you provided is outdated and has some misleading information. Instead, set attribute disabled in JSX. You can simply use Formik's isSubmitting value:

const submitForm = async (formValues) => {
    const url = '/app/submitAgreement';
    let obj = {'formValues': formValues};
    await axios.post(url, obj);
}

<Formik 
    enableReinitialize
    validationSchema={mySchema} 
    onSubmit={ (values) => {
        submitForm(values); // Calls submitForm() function if there are no errors
    }}
    initialValues={initialFormValues}
>
    {
        ({handleSubmit, handleChange, handleBlur, setFieldValue, setFieldTouched, values, touched, isValid, errors, isSubmitting}) 
        => (

            <Form onSubmit={handleSubmit}> {/* Form starts here */}
            ..
            ..
            <Button type="submit" disabled={isSubmitting}
    >Submit</Button>                
    ..
    </Form>

And if you want the button to stay disabled:

const [isSubmitted, setIsSubmitted] = useState(false);

//...

const submitForm = async (formValues) => {
    const url = '/app/submitAgreement';
    let obj = {'formValues': formValues};
    await axios.post(url, obj);
    setIsSubmitted(true);
}

//...
<Button type="submit" disabled={isSubmitting || isSubmitted}

Upvotes: 2

Related Questions