All about Formik & Formik Components and Yup Validation
Tags: formik, react, yup, validation
Published: 2022-06-21 04:52:55

## What is Formik?

Formik is a free and open source, lightweight library for ReactJS or React Native and addresses three key pain points of form creation:
- How the form state is manipulated.
- How form validation and error messages are handled.
- How form submission is handled.

## Why formik?
Creating forms in React or ReactJS can require a significant amount of code, depending on what you need and how you want to manage each form field. As a result, developers are always on the lookout for tools that make their lives easier. One such tool is Formik in React. 

Formik keeps track of your form's state and then exposes it plus a few reusable methods and event handlers (handleChange, handleBlur, and handleSubmit) to your form via props. handleChange and handleBlur work exactly as expected--they use a name or id attribute to figure out which field to update.



Let’s go deep in formik details and talk about most important parts in formik 



## Installation

You can install Formik with NPM or Yarn

NPM
```js
npm install formik --save
```
or

```js
yarn add formik
```

## Formik Components

## **`<Form />`**
Form is a small wrapper around an HTML `<form>` element that automatically hooks into Formik's handleSubmit and handleReset. All other props are passed directly through to the DOM node.

## **`<Formik />`**
<Formik> is a component that helps you with building forms. It uses a render props pattern made popular by libraries like React Motion and React Router.it's accept ValidationSchema and InitialValue which initializes all fields in your form and onSubmit which takes values as a parameter and it is mostly used for post api calls to collect the data out of the form and then we can store the data in the server. 

`<Formik />` Pass handle props to `<Form />` which help us to handle our form like {errors,isValid,handleChange,touched ..etc}

```js
import React from 'react';
import { Formik } from 'formik';

const BasicExample = () => (
  <div>
    <h1>My Form</h1>
    <Formik
      initialValues={{ name: 'jared' }}
      onSubmit={(values) => {
      console.log(values)}
    >
      {props => (
        <form onSubmit={props.handleSubmit}>
          <input
            type="text"
            onChange={props.handleChange}
            onBlur={props.handleBlur}
            value={props.values.name}
            name="name"
          />
          {props.errors.name && <div id="feedback"> 
          {props.errors.name}</div>}
          <button type="submit">Submit</button>
        </form>
      )}
    </Formik>
  </div>
);
```

## **`<Field />`**

`<Field /> `will automagically hook up inputs to Formik. It uses the name attribute to match up with Formik state. `<Field />` will default to an HTML `<input />` element.

we can change display of field using as

```js
//display html dropdown list
<Field as="select" name="color">
    <option value="red">Red</option>
    <option value="green">Green</option>
    <option value="blue">Blue</option>
 </Field>
```

or we can add custom html element passed to `<Field />` and All additional props will be passed through.

```js
// field:An object containing onChange, onBlur, name, and value of 
//   the field
// form:The Formik bag{ name, value, onChange, onBlur }
// meta:An object containing metadata (i.e. value, touched, error, and initialValue)
<Field name="lastName">
    {({field, form , meta }) => (
           <div>
             <input type="text" placeholder="Email" {...field} />
             {meta.touched && meta.error && (
             <div className="error">{meta.error}</div>
             )}
           </div>
     )}
 </Field>
```

## **`<ErrorMessage />`**
`<ErrorMessage />` is a component that renders the error message of a given field if that field has been visited (i.e.touched[name] === true) (and there is an error message present). It expects that all error messages are stored for a given field as a string

```js
// field has been touched and an error exists and subsequent updates.
 <ErrorMessage name="email">
   {msg => <div>{msg}</div>}
 </ErrorMessage>
```

Now let's talk about Most important part in Formik that how to pass custom validation and error messages to Formik.

## Formik Validation

Formik is designed to manage forms with complex validation with ease. Formik supports synchronous and asynchronous form-level and field-level validation. Furthermore, it comes with baked-in support for schema-based form-level validation through Yup. This guide will describe the ins and outs of all of the above.

**ValidationSchema**

Feel free to write your own validators or use a 3rd party library,here we will use Yup for object schema validation. It is small enough for the browser and fast enough for runtime usage. Formik has a special config option / prop for Yup object schemas called validationSchema which will automatically transform Yup's validation errors into a pretty object whose keys match values and touched. This symmetry makes it easy to manage business logic around error messages.

To add Yup to your project, install it from NPM.

```js
 npm install yup --save
```

```js
import React from 'react';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';

const SignupSchema = Yup.object().shape({
  firstName: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  lastName: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  email: Yup.string().email('Invalid email').required('Required'),
});

const initialValues={{
        firstName: '',
        lastName: '',
        email: '',
      }}
export const ValidationSchemaExample = () => (
  <div>
    <h1>Signup</h1>
    <Formik
      initialValues={initialValues}
      validationSchema={SignupSchema}
      onSubmit={values => {
        console.log(values);
      }}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="firstName" />
          {errors.firstName && touched.firstName ? (
            <div>{errors.firstName}</div>
          ) : null}
          <Field name="lastName" />
          {errors.lastName && touched.lastName ? (
            <div>{errors.lastName}</div>
          ) : null}
          <Field name="email" type="email" />
          {errors.email && touched.email ? 
           <div>{errors.email} </div> : null
          }
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);

//The ErrorMessage component can also be used to display error messages.
//<ErrorMessage name="email">
//  {msg => <div>{msg}</div>}
//</ErrorMessage>
```

## Summary
For those creating forms in React, Formik is a very helpful library in React helps achieve simpler state management, form submission, validation, and error message handling. In addition, it is flexible and has lower latency than Redux Form.


Most of the documentation part is taken from [Formik docs](https://formik.org/)