Form and Form Validation in React using Formik and Yup
As a frontend and software engineer in general, security is one of the key concerns when building web applications, second only to performance. So taking time to prevent external form abuse by malicious users is never a wasted effort. We'll be working through form validation and form in React by building a contact form, using Yup and Formik.
Prerequisites
Before you begin this tutorial you'll need the following:
- React knowledge
- Yup Installed
- Formik Installed
Installing React
setting up our project
npx create-react-app yup-formik-validation cd yup-formik-validation yarn start
Formik
Formik is a library that manages form values(data), validation and error messages, and handling of form submissions. Making interacting with form as easy as a walk in the park.
Installing Formik
yarn add formik
Yup
Yup is a JavaScript schema builder for value parsing and validations.
Installing Yup
yarn add yup
Initialize Module
After all installation we'll be working inside our App.js file.
app.js import React, { useState } from 'react'; import { Formik, Field } from 'formik'; import * as Yup from 'yup';
Our next line of action is setting up our Form and form fields using Formik, we'll be working on 4 fields namely:
- First Name Field
- Last Name Field
- Email Field
- Message Field (using Textarea element)
Before we move forward let us talk about formik element and some of its attributes. Formik element housing both Form element and its child element (Field elements).
<Formik>
<Form>
<Field></Field>
</Form>
...
</Formik>
Formik element also has some attributes that are required when setting up a form. Listed below:
- InitialValues: it contains the initial values of our field elements.
initialValues={{ firstName: '', lastName: '', email: '', message: '' }}
- ValidationSchema: houses our Yup validation schema, which we'll be talking about below.
> // declared outside of our App function.
const validationSampleSchema = Yup.object().shape({
firstName: Yup.string().min(1, 'First Name is too
short!').required('First Name field is required'),
lastName: Yup.string().min(1, 'Last Name is too
short!').required('Last Name field is required'),
email: Yup.string().email('Invalid email').required('Email
field is required'),
message: Yup.string().required('Message field is required')
})
Yup has different data type methods validation and conditions methods e.g min() and required()
validationSchema={customValidationSchema}
passing of our custom schema to the validationSchema attribute
- onSubmit : submission function, which is an eventListener.
onSubmit={(values, { setSubmitting, resetForm }) => {
// when the handleSubmit is triggered on our submit button
below, every expression and method actions get triggered
// Reseting our form fields to empty
resetForm({ values: "" });
}}
Rendering our Form and making Formik props and methods available
{(
{
setFieldValue,
values,
errors,
touched,
handleSubmit
}) => (
<>
<form></form>
<>
)}
<form>
<div className='row'>
<div className='col-md-6'>
<div className="form-group mb-3">
<label>First Name</label>
<Field className="form-control" name="firstName"
value={values.firstName} placeholder="First
Name"/>
{errors.firstName && touched.firstName && (<small
className="text-danger">{errors.firstName}
</small>)}
</div>
</div>
<div className='col-md-6'>
<div className="form-group mb-3">
<label>Last Name</label>
<Field name="lastName" className="form-control"
value={values.lastName} placeholder="Last Name"
/>
{errors.lastName && touched.lastName && (<small
className="text-danger">{errors.lastName}
</small>)}
</div>
</div>
<div className='col-md-12'>
<div className="form-group mb-3">
<label>Email</label>
<Field type="email" className="form-control"
value={values.email} name="email"
placeholder="Email" />
{errors.email && touched.email && (<small
className="text-danger">{errors.email}</small>)}
</div>
</div>
<div className="col-md-12">
<div className="form-group mb-3">
<label>Drop Message</label>
<Field name="message">
{({
field,
meta,
}) => (
<div>
<textarea className="form-control"
name="message" id="message"
placeholder="Type here" value=
{values.message} rows="3" {...field} >
</textarea>
{meta.touched && meta.error && ( <small
className="text-danger">{meta.error}
</small>)}
</div>
)}
</Field>
</div>
</div>
</div>
<button type="submit" className='btn btn-sm btn-success'
onClick={handleSubmit}>Submit</button>
</form>
two Field attributes are important to us, in our above code:
- name: automatically hook up inputs to Formik using the name attribute to match up with Formik state.
<Field name={'email'}/>
name attribute matches the property declared in our initialValues.- value: Formik access the value through the value attribute
value={values.fieldName}
e.gvalue={values.email}
Errors
{errors.firstName && touched.firstName && (<small className="text-danger">{errors.firstName}</small>)}
whenever our field has been touched, and it contains an error, display it. The error setup above works with our firstName field.
Submit
<button type="submit" className='btn btn-sm btn-success'
onClick={handleSubmit}>Submit</button>
onClick eventlistener triggers our handleSubmit (Formik method), which is available to us when we rendered our form.
Updated onSubmit Formik attribute
onSubmit={(values, { setSubmitting, resetForm }) => {
// assigning our values from the fields to the payload variable.
const payload = values;
// we have a handleNext function that saves our contact form
field values into a result state.
handleNext(payload);
// Reseting our form fields to empty
resetForm({ values: "" });
}}
const [showResult, setShowResult] = useState(false);
const [result, setResult] = useState({});
const handleNext = (payload) => {
setResult(payload)
setShowResult(true);
}
Yup Formik Validation Contact Form End Result
Conclusion
Working with form in react is very tasking, coupled with trying to set up validation to our form fields, as we all know Form Validation is an integral part of building a web application, and Formik helps in working with forms in React doing the hard part and leaving us to worry more on other important parts in our web app development, same way Yup handles our validations.
Check out the following official documentations to get a broader explanation of our subject matter:
You can also find the full code source on GitHub:
Attributions
Have questions? Facing issues implementing?
Drop a comment let's work through them together.
Do you find this helpful?
You can follow me here on Dev and also on Twitter: