In the post React Form Using Formik's useFormik() Hook we have seen how to create a form in React using Formik library and how to do validation. In that post we used useFormik() hook and did the validation ourselves. Formik provides integration with Yup for object schema validation.
Formik has a special configuration prop for Yup called validationSchema which will automatically transform Yup's validation errors messages into an object whose keys match values/initialValues/touched so that it is easy to map error message with the corresponding form field.
Installing Yup
you can install Yup from NPM or yarn
With npm
npm install yup -save
With yarn
yarn add yup
Using Formik component
To further reduce code and make it more readable Formik comes with components like <Formik />, <Form />, <Field />, and <ErrorMessage />. These formik components use React Context implicitly.
React form example with Formik and Yup
In this example we'll create a form with 5 fields- First Name, Last Name, Join Date, Email and Employment Type.
You can swap useFormik()
hook with Formik component, with that you can pass initial values for the formFields, validation
schema and a submission function.
<Formik initialValues= {{ firstName: '', lastName: '', joinDate: '', email: '', employmentType: 'permanent' }} validationSchema={Yup.object({ firstName: Yup.string() .max(10, 'Must be 10 characters or less') .required('Required'), lastName: Yup.string() .max(15, 'Must be 15 characters or less') .required('Required'), joinDate: Yup.date().max(new Date(), "Join date can't be greater than current date").required('Required'), email: Yup.string().email('Invalid email address').required('Required'), })} onSubmit={(values, { setSubmitting }) => { setTimeout(() => { console.log(JSON.stringify(values, null, 2)); setSubmitting(false); }, 400); }} >
By using Field component you don't need to pass event handlers- onChange, onBlur, value explicitly.
<Field type="text" name="firstName" />
Here is the full React form example using Formik, Field, Form, ErrorMessage components and Yup for validation.
import { ErrorMessage, Field, Form, Formik } from "formik"; import * as Yup from 'yup'; const EmployeeInfoForm = () => { return( <Formik initialValues= {{ firstName: '', lastName: '', joinDate: '', email: '', employmentType: 'permanent' }} validationSchema={Yup.object({ firstName: Yup.string() .max(10, 'Must be 10 characters or less') .required('Required'), lastName: Yup.string() .max(15, 'Must be 15 characters or less') .required('Required'), joinDate: Yup.date().max(new Date(), "Join date can't be greater than current date").required('Required'), email: Yup.string().email('Invalid email address').required('Required'), })} onSubmit={(values, { setSubmitting }) => { setTimeout(() => { console.log(JSON.stringify(values, null, 2)); setSubmitting(false); }, 400); }} > {({ errors, touched }) => ( <Form> <div className="form-group col-sm-4 mb-2" > <label htmlFor="firstName" className="form-label">First Name</label> <Field type="text" name="firstName" placeholder="Enter firstname" className={'form-control' + (errors.firstName && touched.firstName ? ' is-invalid' : '')} /> <ErrorMessage name="firstName" component="div" className="invalid-feedback" /> </div> <div className="form-group col-sm-4 mb-2" > <label htmlFor="lastName" className="form-label">Last Name</label> <Field type="text" name="lastName" className={'form-control'+ (errors.lastName && touched.lastName ? ' is-invalid' : '')}/> <ErrorMessage name="lastName" component="div" className="invalid-feedback"/> </div> <div className="form-group col-sm-4 mb-2" > <label htmlFor="joinDate" className="form-label">Join Date</label> <Field type="date" name="joinDate" className={'form-control'+ (errors.joinDate && touched.joinDate ? ' is-invalid' : '')}/> <ErrorMessage name="joinDate" component="div" className="invalid-feedback"/> </div> <div className="form-group col-sm-4 mb-2" > <label htmlFor="email" className="form-label">Email</label> <Field type="email" name="email" className={'form-control'+ (errors.email && touched.email ? ' is-invalid' : '')}/> <ErrorMessage name="email" component="div" className="invalid-feedback"/> </div> <div className="form-group col-sm-4 mb-2" > <label htmlFor="employmentType" className="form-label">Employment Type:</label> <Field as="select" name="employmentType" className="form-select " > <option value="permanent">Permanent</option> <option value="contract">Contract</option> </Field> </div> <div className="form-group col-sm-4 mb-2" > <button type="submit" className="btn btn-primary">Submit</button> </div> </Form> )} </Formik> ); } export default EmployeeInfoForm;
Some important points to note here-
-
In the example Bootstrap 5 is used for styling. You can import Bootstrap by adding following to the <head>
section of the index.html file.
<link rel="stylesheet" href=https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous" />
- Initial values for the form fields are as empty fields except for the employmentType which is a drop-down list where pre-selected option is given.
- Validation is done using Yup which is quite self-explanatory. For join date it should not go beyond the current date.
- The submission function (onSubmit) logs the form values.
- In the <Form> section some of the Bootstrap classes like
form-group
,form-label
,form-control
,is-invalid
,invalid-feedback
are used. - If there is an error then apart from
form-control
,is-invalid
class is also added. - The <Field> component by default will render an <input> component. <Field> also accepts a few
other props to let you render other elements like textarea, select.
<Field name="message" as="textarea" /> <Field name="employmentType" as="select" />
With Error Messages
With All Form Values
That's all for the topic React Form + Formik + Yup Validation Example. If something is missing or you have something to share about the topic please write a comment.
You may also like
- React Form Creation and Validation Using React Hooks
- React Example - Insert New Object in an Array
- React useReducer Hook With Examples
- React Portals With Examples
- Java Program to Find The Maximum Element in Each Row of a Matrix
- Injecting Null and Empty String Values in Spring
- Spring Data JPA Pagination and Sorting Example
No comments:
Post a Comment