Form validation in react and next JS using Formik and Yup
Tags: react, form, nextjs, javascript
Published: 2023-10-01 15:56:48

In this article, I will show you how to implement react form validation using Formik and Yup.

The form has the following fields:
Name: required
Age: required and the maximum age limit is 50
Email: required
Note: we will add regex for complex email using the matches function of yup.
Currency: required
Note: we will also handle multi-select using yup.array().min(1).
Terms and Conditions: required 


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

Successful form submissions look like this below 

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

**_Technology_**

1. react [18.2.0] + Vite 
2. formik 
3. yup
4. material ui
5. typescript

**_Configure project_**

We need to make a new React JS project using Vite and install all the above dependencies

```
npm install formik yup @mui/material @emotion/react @emotion/styled

or 
yarn add formik yup @mui/material @emotion/react @emotion/styled
```

After project setup 
I will make a new component for form building using material UI 
[BookingForm.tsx]

There are 2 ways to implement validation using Formik 

- useFormik
- Formik,Field,setFieldData etc 

I am using formik hook in this tutorial!

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

Here is Complete file 

```
import {
  Button,
  Checkbox,
  FormControlLabel,
  FormHelperText,
  InputLabel,
  MenuItem,
  TextField,
} from '@mui/material';
import * as yup from 'yup';
import { useFormik } from 'formik';

const style = {textAlign: 'start'}
const formStyle = {marginBottom: '10px'}
const currencies = [
  {
    value: 'USD',
    label: '$',
  },
  {
    value: 'EUR',
    label: '€',
  },
  {
    value: 'BTC',
    label: '฿',
  },
  {
    value: 'JPY',
    label: '¥',
  },
];

const BookingForm = () => {
  const validationSchema = yup.object({
    name: yup.string().required('Name is required'),
    age: yup
      .number()
      .required('Age is required')
      .max(50, 'Your age must less from fifty'),
    email: yup
      .string()
      .email('Enter a valid email')
      .required('Email is required'),
    currency: yup.string().required('Currency is required'),
    terms: yup.bool().oneOf([true], 'You must accept the terms and conditions')
  });

  const formik = useFormik({
    initialValues: {
      name: '',
      age: '',
      email: '',
      currency: '',
      terms: false,
    },

    validationSchema,
    onSubmit: (values) => {
      alert(JSON.stringify(values, null, 2));
    },
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <div style={formStyle}>
        <InputLabel sx={style}>Name</InputLabel>
        <TextField
          type='text'
          name='name'
          placeholder='name*'
          size='small'
          value={formik.values.name}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          error={formik.touched.name && Boolean(formik.errors.name)}
          helperText={formik.touched.name && formik.errors.name}
          fullWidth
        />
      </div>
      <div style={formStyle}>
        <InputLabel sx={style}>Age</InputLabel>
        <TextField
          type='number'
          name='age'
          placeholder='age*'
          size='small'
          value={formik.values.age}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          error={formik.touched.age && Boolean(formik.errors.age)}
          helperText={formik.touched.age && formik.errors.age}
          fullWidth
        />
      </div>
      <div style={formStyle}>
        <InputLabel sx={style}>Email</InputLabel>
        <TextField
          type='text'
          name='email'
          placeholder='email'
          size='small'
          value={formik.values.email}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          error={formik.touched.email && Boolean(formik.errors.email)}
          helperText={formik.touched.email && formik.errors.email}
          fullWidth
        />
      </div>
      <div style={formStyle}>
        <InputLabel sx={style}>Currency</InputLabel>
        <TextField
          id='filled-select-currency'
          select
          defaultValue='EUR'
          name='currency'
          fullWidth
          size='small'
          value={formik.values.currency}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          error={formik.touched.currency && Boolean(formik.errors.currency)}
          helperText={formik.touched.currency && formik.errors.currency}
        >
          {currencies.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </TextField>
      </div>

      <div style={{textAlign: 'start'}}>
        <FormControlLabel
          control={
            <Checkbox
              name='terms'
              onChange={formik.handleChange}
              value={formik.values.terms}
              onBlur={formik.handleBlur}
            />
          }
          label='Terms and condition'
          name='terms'
        />
        {formik.errors.terms && <FormHelperText sx={{color: 'red'}}>{formik.errors.terms}</FormHelperText>}
      </div>

      <Button type='submit' variant='contained' sx={{ mt: '15px' }}>
        Submit
      </Button>
    </form>
  );
};

export default BookingForm;

```

Then use BookingForm component into Main file called App.tsx


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

Also, You can fork my GitHub repository for this lesson
https://github.com/ZeeshanMustfai/formik-validation

                         **_ Thanks _**



Follow me on Linkedin 
https://www.linkedin.com/in/zeeshan-mustfai-2bb4aaa9/
 
Follow me on github
https://github.com/ZeeshanMustfai