Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass values from a component into Formik multi-step form wizard?

As the title said. I have a stateless component based on react-bootstrap-typeahead and a form wizard based on the formik multi-step wizard example found in the docs.

However, I am unable to pass the values I got from the typeahead component into formik. I can't access setFieldValue.

    const FormElements = setFieldValue => (
        <Wizard
          initialValues={FORM_VALUES}
          onSubmit={(values, actions) => {
            sleep(300).then(() => {
              window.alert(JSON.stringify(values, null, 2));
              actions.setSubmitting(false);
            });
          }}
        >
          <Wizard.Page>
            <GoogleMapsPlaceLookup
              value={location => {
                console.log("I got the value correctly from my child: ", location);
              }}
            />
          </Wizard.Page>
        </Wizard>
    );

    export default FormElements;

How do I inject this value into Formik, so it can be processed onSubmit. Any pointer or help will be appreciated. Thanks

like image 726
adetoola Avatar asked Feb 02 '19 12:02

adetoola


1 Answers

Formik author here...

In the example, the <Wizard /> component renders <Formik> so the setFieldValue in your FormElements function is not actually in the correct scope. If you need access to setFieldValue within one of your wizard's pages, you can get it out of a custom <Field>, using connect() higher order component with a custom component, or directly from Formik context using <FormikConsumer> render prop.

My suggestion would be to use Formik's <Field> component with a render prop like so:

const FormElements = () => (
  <Wizard
    initialValues={FORM_VALUES}
    onSubmit={(values, actions) => {
      sleep(300).then(() => {
        window.alert(JSON.stringify(values, null, 2));
        actions.setSubmitting(false);
      });
    }}
  >
    <Wizard.Page>
      <Field name="location">
        {({ field, form }) => (
          <GoogleMapsPlaceLookup
            value={field.value /* make sure to somehow connect Formik's stored value state to the input */}
            onChange={location => {
              console.log('I got the value correctly from my child: ', location);               
              // Manually set Formik values.location and trigger validation
              form.setFieldValue('location', location);
            }}
          />
        )}
      </Field>
    </Wizard.Page>
  </Wizard>
);
like image 114
jaredpalmer Avatar answered Oct 29 '22 16:10

jaredpalmer