Simplifying React Form Validation with Formik & Yup
Sivanand GKamath
3 min read
Table of contents
// Author: Sivanand G Kamath
// Dated : 04/06/2023
/*
Formik and Yup: Reducing Effort and Enhancing Convenience in Form Management
Formik is a powerful React library designed to simplify form management, particularly for complex forms.
It handles form state, validation, and submission efficiently, reducing the need for repetitive code.
With Formik, developers can easily manage form input, track form values, errors, and submission status,
ensuring a smoother form-building process.
Yup, a schema validation library, works seamlessly with Formik to handle form validation.
It simplifies defining validation rules, ensuring input accuracy with minimal code.
Together, Formik and Yup streamline form development, improve code maintainability,
and offer a more organized approach to form validation, saving time and effort.
sample:-
https://codesandbox.io/p/sandbox/formik-and-yup-tutorial-8d5vvq
*/
import { Button, Card, CardContent, CardHeader, Checkbox, Container, FormControl, FormControlLabel, FormHelperText, FormLabel, Grid, MenuItem, Radio, RadioGroup, Select, TextField } from '@mui/material';
import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import React from 'react'
// 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
const FormikForm = () => {
/*
*********** Formik 😍️***********
Formik consists of mainly 4 components: - initialValues, ValidationSchema, OnSubmit, and the return component which is written in the return part of the React page
eg:
const formik = useFormik({
1️⃣️ initialValues: { name: formData.name || '', // in case we need to repopulate the value, here I used formData variable
//...
},
2️⃣️ validationSchema: {
if(formik.values.name.length <2){
alert("Please provide proper Name")
}
//...
},
3️⃣️ onSubmit:(values) => {
console.log(values);
// or write form submit logic here
}
})
In return part, the below is the syntax
4️⃣️ <TextField
label="Name"
name="text"
fullWidth
value={formik.values.name}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.name && Boolean(formik.errors.name)} // error msg
helperText={formik.touched.name && formik.errors.name}
/>
***************--------------------------*******************
Yup simplifies by doing validations such as email, passwords etc.
here I modularized the code so that it becomes easy to understand!!🙂️
*/
const validationSchema = Yup.object().shape({
text: Yup.string().required('Required'),
select: Yup.string().required('Required'),
checkbox: Yup.bool().oneOf([true], 'Required'),
radio: Yup.string().required('Required'),
//email: Yup.string().email('Invalid email format').required('Email Id is required') //this is how YUP simplifies the validation of email etc
});
const formik = useFormik({
initialValues: {
text: '',
select: '',
checkbox: false,
radio: '',
datetime: null,
multiSelect: [] || '',
},
validationSchema: validationSchema,
onSubmit: (values) => {
console.log(values);
},
});
return (
<div>
<Container>
<Card>
<CardHeader title="FormikForm with Yup validation"></CardHeader>
<CardContent>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<form onSubmit={formik.handleSubmit}>
<Grid container spacing={2}>
<Grid item xs={12} md={12} lg={12} xl={12}>
<TextField
label="Text Field"
name="text"
fullWidth
value={formik.values.text}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.text && Boolean(formik.errors.text)}
helperText={formik.touched.text && formik.errors.text}
/>
</Grid>
<Grid item xs={12} md={12} lg={12} xl={12}>
<FormControl fullWidth>
<FormLabel>Select Field</FormLabel>
<Select
name="select"
fullWidth
value={formik.values.select}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.select && Boolean(formik.errors.select)}
>
<MenuItem value="">None</MenuItem>
<MenuItem value="option1">Option 1</MenuItem>
<MenuItem value="option2">Option 2</MenuItem>
</Select>
{formik.touched.select && formik.errors.select && (
<FormHelperText error>{formik.errors.select}</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12} md={12} lg={12} xl={12}>
<FormControl fullWidth >
<FormLabel>Multi Select</FormLabel>
<Select
name="multiSelect"
multiple
fullWidth
value={formik.values.multiSelect}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
renderValue={(selected) => selected.join(', ')}
error={formik.touched.multiSelect && Boolean(formik.errors.multiSelect)}
>
<MenuItem value="option1">Option 1</MenuItem>
<MenuItem value="option2">Option 2</MenuItem>
<MenuItem value="option3">Option 3</MenuItem>
</Select>
{formik.touched.multiSelect && formik.errors.multiSelect && (
<FormHelperText error>{formik.errors.multiSelect}</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12} md={12} lg={12} xl={12}>
<FormControlLabel
control={
<Checkbox
name="checkbox"
fullWidth
checked={formik.values.checkbox}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.checkbox && Boolean(formik.errors.checkbox)}
/>
}
label="Checkbox"
/>
</Grid>
<Grid item xs={12} md={12} lg={12} xl={12}>
<FormControl component="fieldset">
<FormLabel component="legend">Radio Buttons</FormLabel>
<RadioGroup
name="radio"
fullWidth
value={formik.values.radio}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.radio && Boolean(formik.errors.radio)}
>
<FormControlLabel value="option1" control={<Radio />} label="Option 1" />
<FormControlLabel value="option2" control={<Radio />} label="Option 2" />
<FormControlLabel value="option3" control={<Radio />} label="Option 3" />
</RadioGroup>
{formik.touched.radio && formik.errors.radio && (
<FormHelperText error>{formik.errors.radio}</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12} md={12} lg={12} xl={12}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DateTimePicker
label="Date and Time"
name="datetime"
fullWidth
value={formik.values.datetime}
onChange={(value) => formik.setFieldValue('datetime', value)}
onBlur={formik.handleBlur}
renderInput={(params) => <TextField {...params} />}
error={formik.touched.datetime && Boolean(formik.errors.datetime)}
helperText={formik.touched.datetime && formik.errors.datetime}
/>
</LocalizationProvider>
</Grid>
<Grid item xs={12} md={12} lg={12} xl={12}>
<Button type="submit" variant="contained" color="primary">Submit</Button>
</Grid>
</Grid>
</form>
</LocalizationProvider>
</CardContent>
</Card>
</Container>
</div>
)
}
export default FormikForm
0
Subscribe to my newsletter
Read articles from Sivanand GKamath directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by