Dynamic forms with validation React + Formik
Tags: react, javascript, formik, webdev
Published: 2022-10-07 11:06:16

So recently, I was asked to implement a feature in React where users can add up to three pieces of information during registration. I said to myself, this shouldn't be a problem, until I realized I had to validate each input so as not to enable users to submit an empty form. I am a big fan of using formik and yup as validation, so I had to read up formik documentation and I came across a very easy way of doing it, which I'll be sharing. By the way, it is not that much different from react-hook form.

Set up your react project, install formik, and yup. Formik is a small library that helps you with the 3 most annoying parts:

1. Getting values in and out of the form state
2. Validation and error messages
3. Handling form submission

While Yup is a JavaScript schema builder for value parsing and validation. Proceed to create each part of the application as a component. Create your input component within your project. You will need to import errorMessage along with the input from formik. <ErrorMessage /> is a component that renders the error message of a given field if that field has been visited. It expects that all error messages are stored for a given field as a string.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4audusdawjcffv0rwfa.png)

Create the yup schema, which will be used to validate the form.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzlly6prmxa5lmj12jjz.png)

Create initial values, which will be passed into the formik form as the default values of all input fields. The initial values should be in from of key-value pair, the key will be passed down to formik field array which will enable us to create inputs on the fly as shown in the image below

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlnjz0ra2veucjdwekl1.png)

Now to the main application itself. Create the form, and give it some styling just to make it look good. Use the formik wrapper to wrap the form, import, and pass your initial values and validation into the formik wrapper. import fieldArray from formik as this is what is going to be used to create the dynamic form. It accepts a name property, the name should be the same as the key used for the initial values. Destructure values and set values from FormikProps, which you will have access to inside the form. We will use values to display a close button when the form length is greater than one. setValues will be used to increase the length of the form. 

Each input will need a name for formik to identify them individually. We will be creating 3 inputs: one for module name, transcript, and description; and two buttons to add more and submit. When a user clicks on "add more", we want to create another form with the same three inputs. Each input needs a unique name, which formik will use for validation. You will need to map through the values. Remember that initial values are in the key-value pair, map through values, and access the key of the initial values. We will need access to the index as well, so endeavor to pass that to the map function. Because each input needs a unique name, which must be created dynamically, pass the key of initial values concatenated with the index and the value in the initial values. Here is a code snippet of what your component should look like,  

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oig41khycc1orntrr9pd.png)

When the user clicks on add more, we display a close button for each form and when the length is one we hide the close button. In our add more and close buttons, we are going to be create two functions, one to increment the form and the other to delete a form.
For our add more, we will create a function `updateForm` which we will pass in values and set values as arguments into the function. We will have access to the current values and we will be able to increment them using set values. While for our function to delete a form we will be passing the index along with values and set values, which will enable us to track which form the user wants to close check below for the functions

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmxfrntkx4ksc85xm5re.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmz2zjetyci6lxaqnbdy.png)

With the above functions when a user now clicks add more a new form will be pushed into the current array setValues will help us re-render it so as to have the newly added form and when the user clicks on close the delete function will help users remove the particular form the user wants to close. A final function we will need is a submit function. In formik a button without a type is treated as a type of submit which formik will tie to its handleSubmit, so all we need is a button with or without a type of submit. Formik directly gives us access to the values in the handleSubmit and when clicked formik also runs the validation and creates schemas for each form.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhxe6t96e4pdxlygbhf1.png)

If no errors, you have the values in an array of objects. Thanks for reading.

Here is a link to the full code on my code-sandbox
https://codesandbox.io/s/affectionate-bartik-ugezfx?file=/src/app.js