DEV Community

ZeeshanMustfai
ZeeshanMustfai

Posted on • Updated on

Form validation in react and next JS using Formik and Yup

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

Successful form submissions look like this below

Image description

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
Enter fullscreen mode Exit fullscreen mode

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

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;

Enter fullscreen mode Exit fullscreen mode

Then use BookingForm component into Main file called App.tsx

Image description

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

                     **_ Thanks _**
Enter fullscreen mode Exit fullscreen mode

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

Follow me on github
https://github.com/ZeeshanMustfai

Top comments (0)