Ajai
Ajai

Reputation: 391

Unable to disable button outside Formik using innerRef

I'm trying to use innerRef in Formik to get the isValid and dirty outside the Formik to disable the submit button. I have attached the coding below.

import React, { useRef } from "react";
import { Button, Checkbox, Select } from "antd";
import { useTranslation } from "react-i18next";
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import { FloatLabel } from "../../../UIComponent/index";
import { roles } from "../../Roles/sample";
import { filter, sort } from "../../../_util/select";

const AddEditUser = ({ setVisible, visible, users }) => {
    const { t } = useTranslation();
    const { Option } = Select;
    let formRef = useRef({});

    const userValidationSchema = Yup.object().shape({
        firstName: Yup.string().required("First Name is Required."),
        userName: Yup.string().required("User Name is Required.")
            .test("username-unique", "User Name Already Exist.",
                (value) => users.find(el => el.name?.toLowerCase() === value?.toLowerCase()) ? false : true),
        password: Yup.string().required("Password is Required.")
    });

    return <div className="formContainer h-100">
        <OverlayScrollbarsComponent className="formBody">
            <Formik
                innerRef={formRef} 
                initialValues={{
                    firstName: "",
                    lastName: "",
                    userName: "",
                    role: "",
                    password: ""
                }}
                validationSchema={userValidationSchema}
                onSubmit={async values => { }}
                onChange={()=> console.log("sss")}
            >
                {({
                    values,
                    setFieldValue,
                    setFieldTouched,
                    errors,
                    touched
                }) => <Form noValidate>
                        <div className="innerContainer row">
                            <div className="col-12 mb-2 ">
                                <FloatLabel label="First Name" name="firstName" value={values.firstName}>
                                    <Field
                                        type="text"
                                        className="w-100 form-control"
                                        name="firstName" />
                                    <ErrorMessage
                                        name="firstName"
                                        component="span"
                                        className="errorMessage"
                                    />
                                </FloatLabel>
                            </div>
                            <div className="col-12 mb-2">
                                <FloatLabel label="Last Name" name="lastName" value={values.lastName}>
                                    <Field
                                        type="text"
                                        className="w-100 form-control"
                                        name="lastName" />
                                    <ErrorMessage
                                        name="lastName"
                                        component="span"
                                        className="errorMessage"
                                    />
                                </FloatLabel>
                            </div>
                            <div className="col-12 mb-2">
                                <FloatLabel label="User Name" name="userName" value={values.userName}>
                                    <Field
                                        type="text"
                                        className="w-100 form-control"
                                        name="userName" />
                                    <ErrorMessage
                                        name="userName"
                                        component="span"
                                        className="errorMessage"
                                    />
                                </FloatLabel>
                            </div>
                       
                            <div className="col-12 mb-2">
                                <FloatLabel label="Password" name="password" value={values.password}>
                                    <Field
                                        type="password"
                                        className="w-100 form-control"
                                        name="password" />
                                    <ErrorMessage
                                        name="password"
                                        component="span"
                                        className="errorMessage"
                                    />
                                </FloatLabel>
                            </div>
                    </Form>
                }
            </Formik>

        </OverlayScrollbarsComponent>
        <footer>
            <Button className="button"
                disabled={!(formRef.isValid && formRef.dirty)}>
                {t("submit")}
            </Button>
        </footer>
    </div>
};

export default AddEditUser;

In this above example im using innerRef in Formik to get thier properties out of the form to disable the button but not working as expected. I tried of putting console inside innerRef I saw the value is updating

   innerRef={(ref)=> {
     console.log(ref);  // here I'm seeing the value updating whenever the form properties 
                           value changes
     formRef = ref;

   }}

but not disabling the button. Can someone help how to get properties out of formik to disable the Submit button

Upvotes: 3

Views: 1038

Answers (1)

Silvino Escalona
Silvino Escalona

Reputation: 321

If you read https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs carefully. You will notice that to make use of the ref, you have to use ref.current.

So disabled={!(formRef.isValid && formRef.dirty)}> should be disabled={!(formRef.current.isValid && formRef.current.dirty)}>

Upvotes: 0

Related Questions