SolidSnake
SolidSnake

Reputation: 1529

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.

Upvotes: 41

Views: 60558

Answers (3)

omzer
omzer

Reputation: 1598

A good approach to go with here is to use the useFormikContext function to extract setFieldValue from.

The file where the component is located:

const OtherComponent = () => {
    const { setFieldValue } = useFormikContext();

... rest of your code here ...

And you can update any field by: setFieldValue(field name, field value)

Make sure the OtherComponent is a child of Formik to receive the respective FormikContext.

Upvotes: 6

Hamza Iqbal
Hamza Iqbal

Reputation: 37

While using useFormik hook, API provides this function: validation.setFieldValue(key,value)

Upvotes: 0

SolidSnake
SolidSnake

Reputation: 1529

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();
  };

Upvotes: 57

Related Questions