DEV Community

ZeeshanMustfai
ZeeshanMustfai

Posted on • Edited on

11

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)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay