How to share Formik initialValues among different components before or after they have been set?

Viewed 2884

I'm having trouble understanding Formik and how it manages state. I have multiple components in my app that have forms. These forms have a lot of overlap on purpose. When I get values in one component, I would like the other components to have access to those values too.

I have contemplated using useState or useReducer for each and everyone of the values but I've done some reading and found out that Formik manages state itself? So my problem here would be really just to access the values from 'initialValues' in a certain component in different components?

import { Formik, Field, Form, ErrorMessage } from 'formik';
import * as Yup from 'yup';

<Formik 
     initialValues={{ name: '', ... }} //how can I use these values in other components? 
                                       //how can I 'save' them so that if the user 
                                       //accesses another page with a form, 
                                       //the data that has already been provided is accessible?

     onSubmit={(values, { setSubmitting }) => {
         setTimeout(() => {
            alert(JSON.stringify(values, null, 2)); 
            setSubmitting(false);
         }, 400)
     }}
>

  <Form>
    <label htmlFor="name">Name</label>
      <Field maxLength="51"
             name="name"  
             type="text" 
      />
      <ErrorMessage name="name" />
      ...
  </Form>

</Formik>
1 Answers

As the prop name implies these are simply the initial values for the form when the form mounts. Formik does indeed store state as it tracks the inputs value, touched and error state and how they are updated controlling the input elements. As Formik uses the context API under the hood, the Formik state is only available to children of the component. To access this Formik state (sometimes collectively referred to Formik bag) you can use a render prop pattern (example visible here) or the useFormikContext hook

Ultimately if you require multiple components (e.g implementation of multiple different pages) you will need to transfer state between different components. I would advise here not overlooking the fact that you could have multiple components within one component that are visually separated on the page (example). If you really want to transfer state between different components you can do this in a number of ways.

  1. Saving and re-fetching from an API (good for different pages when an API is in use)
  2. Saving in react context that encapsulates all of the forms that need the data - you can update the context in either the "onSubmit" or if you use render props as the child of you can update context on each re-render (caused by any change)

If you do this you should read up on the reinitialise prop on the component too - https://jaredpalmer.com/formik/docs/api/formik#enablereinitialize-boolean

Related