Search code examples
formik

How to update Formik Field from external actions


I am trying to update a Formik field from a modal screen. The modal returns the data and set them into the pageState. Considering that my Fomik Form has "enableReinitialize", the field update works fine. However, if the form is in "dirty" state, which means, some other fields in the form were updated, this process to update a field does not work anymore. The field itself is a readonly field and the only way to the user populate the data is clicking on a button and selecting the data from the Modal.

Does anybody knows a workaround to this issue?

React 16.8.6 Formik 1.5.8

A summary of my form:

<Formik
        enableReinitialize={true}
        initialValues={props.quoteData}
        validationSchema={QuoteFormSchema}
        onSubmit={values => {
          props.onSubmit(values);
        }}
      >


{({ values, setFieldValue }) => (

<Label for='customerName'>Customer:</Label>
                  <Field
                    type='text'
                    name='customerName'
                    id='customerName'
                    value={values.customerName}
                    onClick={props.showCustomerModal}
                    onChange={e => {
                      setFieldValue('customerName', e.target.value);
                    }}
                    component={customInputFormModal}
                  />

I need to update the Formik field as soon as a new data is selected from the modal. Even if the form is dirty or not.

I also tried on ComponentDidUpdate() to set the data from the state directly to the field. However, the Formik state (using tags) does not show any changes...

Also, I tried:

1) to use OnChange + setValue. However, it seems to work only from the user input (having the field enabled and allowing the user type some data). Setting data direct in the field does not work.

2) Formik-effect. However without any success.


Solution

  • I solved my problem rendering my modal component inside my Fomik functional component. And then, for the callBack of my modal component I just wrote a method that will receive the Formiks setFieldValue reference. Then was possible to manually set the data into Formik's state:

    My Modal Component inside Formik's component:

    <Formik
            enableReinitialize={true}
            initialValues={props.quoteData}
            validationSchema={QuoteFormSchema}
            onSubmit={values => {
              props.onSubmit(values);
            }}
          >
            {({ values, setFieldValue }) => (
              <Form id='myForm'>
                <CustomerPopup
                  showModal={showModal}
                  close={() => toggleCustomerModal()}
                  onSelect={data => onSelectCustomerHandler(data, setFieldValue)}
                />
    

    My method to update Formik's state:

    // Handle Customer Selection from Modal Component
      const onSelectCustomerHandler = (data, setFieldValue) => {
        setFieldValue('customerName', data.name);
        setFieldValue('customerId', data.id);
        toggleCustomerModal();
      };