Search code examples
reactjsformikmetronic

Formik doesn't update a value given by state


I am using Metronic React Template and customizing a form. Some of my form fields' values are kept in a state. When I submit the form with filled inputs, those values are returning as empty strings even though the state is updated.

Here is my summarized code:

const [currentPhoneNumber, setCurrentPhoneNumber] = useState("")

const handlePhoneNumberChange = (e) => {
    const asYouType = new AsYouType()
    const formatted = asYouType.input(e.target.value)

    setCurrentPhoneNumber(formatted)
}

const submitForm = async (values) => {
    console.log(values.phoneNumber) // returns "" when Field has value={currentPhoneNumber}
}

<Formik
    initialValues={initValues}
    validationSchema={schemas[currentSchemaIndex]}
    onSubmit={submitForm}
    enableReinitialize
>
    {() => (
        <Form
            className="py-20 w-100 w-xl-700px px-9"
            noValidate
            id="kt_create_account_form"
            placeholder={undefined}
        >
            // Not working
            <Field
                className="form-control form-control-lg form-control-solid"
                onChange={handlePhoneNumberChange}
                value={currentPhoneNumber}
                name="phoneNumber"
            />

            // Working
            <Field
                className="form-control form-control-lg form-control-solid"
                name="phoneNumber"
            />
        </Form>
    )}
</Formik>

In similar questions the enableReinitialize property does the trick but not for me.


Solution

  • You do not need to give any state when using formik. Because formik handles its own state. Then you need to use formik's methods to update. Here fixed version of your code:

    import React from 'react';
    import { Formik, Field, Form, setFieldValue } from 'formik';
    import { AsYouType } from 'path'
    
    export const AnyComponent = () => {
      // submit form is a formik method that gets values directly from formik
      const submitForm = async (values) => {
        console.log(values)
      }
      return (
        <Formik
          initialValues={{currentPhoneNumber: ''}}
          validationSchema={schemas[currentSchemaIndex]}
          onSubmit={submitForm}
          enableReinitialize
        >
        {(props) => (
            <Form
                className="py-20 w-100 w-xl-700px px-9"
                noValidate
                id="kt_create_account_form"
                placeholder={undefined}
            >
                // Not working
                <Field
                    className="form-control form-control-lg form-control-solid"
                    onChange={(e) => {
                      const asYouType = new AsYouType();
                      const formatted = asYouType.input(e.target.value);
                      setFieldValue("currentPhoneNumber", formatted)
                    }}
                    value={props.values.currentPhoneNumber}
                    name="phoneNumber"
                />
    
                // Working
                <Field
                    className="form-control form-control-lg form-control-solid"
                    name="phoneNumber"
                />
            </Form>
          )}
        </Formik>
      )
    }