Formik + Yup: A Powerful Duo for Handling Forms in Node.js
Form and validation using Formik + Yup in reactJS
Formik + Yup: A Powerful Duo for Handling Forms in Node.js
Introduction
Formik and Yup are two powerful libraries that make working with forms in Node.js applications a breeze. Formik handles the form state and validation, while Yup provides a flexible and expressive way to define validation schemas. Together, they streamline the process of creating robust and user-friendly forms.
Installation
Install the necessary packages using npm or yarn:
Bash
npm install formik yup
Basic Usage
Import the required components:
import { Formik, Form, Field, ErrorMessage } from 'formik'; import * as Yup from 'yup';
Define a validation schema using Yup:
const validationSchema = Yup.object({ email: Yup.string().email('Invalid email').required('Required'), password: Yup.string().min(8, 'Password must be at least 8 characters').required('Required'), });
Wrap your form components with Formik:
<Formik initialValues={{ email: '', password: '' }} validationSchema={validationSchema} onSubmit={(values, { setSubmitting }) => { // Handle form submission here }} > {({ isSubmitting, values, errors }) => ( <Form> <Field type="email" name="email" /> <ErrorMessage name="email" component="div" /> <Field type="password" name="password" /> <ErrorMessage name="password" component="div" /> <button type="submit" disabled={isSubmitting}> Submit </button> </Form> )} </Formik>
Key Points
Formik manages form state, validation, and submission handling.
Yup provides a declarative way to define validation rules.
Formik integrates seamlessly with Yup for unified validation.
Use
initialValues
to set initial form data.Access form values, errors, and submission status using Formik's props.
Display error messages with
ErrorMessage
components.Handle form submission within the
onSubmit
callback.
Another examples how to use Formik + Yup
1. Basic Form Submission:
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const validationSchema = Yup.object({
name: Yup.string().required('Name is required'),
email: Yup.string().email('Invalid email').required('Email is required'),
});
const BasicForm = () => (
<Formik
initialValues={{ name: '', email: '' }}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting }) => {
console.log('Submitted values:', values);
setSubmitting(false);
}}
>
{({ isSubmitting, values, errors }) => (
<Form>
<Field type="text" name="name" />
<ErrorMessage name="name" component="div" />
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
);
2. Handling Nested Forms:
const NestedForm = () => (
<Formik
initialValues={{
user: {
name: '',
email: '',
address: {
street: '',
city: '',
},
},
}}
validationSchema={/* ... */}
onSubmit={/* ... */}
>
{({ values }) => (
<Form>
<Field type="text" name="user.name" />
<Field type="email" name="user.email" />
<Field type="text" name="user.address.street" />
<Field type="text" name="user.address.city" />
</Form>
)}
</Formik>
);
3. Validating Password Strength:
const passwordSchema = Yup.string()
.required('Password is required')
.min(8, 'Password must be at least 8 characters')
.matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
'Password must contain at least one uppercase, lowercase, number, and special character'
);
4. Creating Custom Validation Rules:
const customSchema = Yup.object({
age: Yup.number()
.typeError('Age must be a number')
.min(18, 'You must be at least 18 years old'),
});
5. Handling Asynchronous Validation:
const checkUsernameAvailability = async (username) => {
// Simulate an API call to check username availability
const isAvailable = await /* ... */;
return isAvailable ? true : 'Username is already taken';
};
const validationSchema = Yup.object({
username: Yup.string()
.required('Username is required')
.test(
'username-available',
'Username is not available',
async (value) => await checkUsernameAvailability(value)
),
});
6. Displaying Conditional Error Messages:
{errors.email && touched.email && (
<div className="error-message">
{errors.email}
</div>
)}
7. Using Formik with Other Form Components:
import { useFormikContext } from 'formik';
const CustomInput = () => {
const { values, errors, touched, handleChange } = useFormikContext();
// ...
};