- Published on
How to Use Conditional Validation in Formik with Yup
- Authors
- Name
- Ripal & Zalak
Master Conditional Validation in Yup
Conditional validation is a powerful feature of Yup, a JavaScript schema builder, allowing you to apply dynamic rules based on the values of other fields. In this article, we will explore how to effectively use this feature, particularly when integrated with Formik for managing forms in React.
Why Use Conditional Validation?
Conditional validation is essential when:
- A field's requirement depends on another field (e.g., email is required only if a checkbox is selected).
- You need to validate dynamic or complex forms with dependencies.
Example: Email Validation Based on Checkbox
Here's how you can use Yup's when
method to conditionally validate an email field based on a checkbox:
import * as Yup from 'yup'
const validationSchema = Yup.object().shape({
showEmail: Yup.boolean(),
email: Yup.string()
.email('Invalid email format')
.when('showEmail', {
is: true, // Condition to apply validation
then: Yup.string().required('Email is required'),
otherwise: Yup.string(),
}),
})
Explanation:
showEmail
Field: Defined as a boolean to control the condition.when
Method: Dynamically changes the validation rules based on the value ofshowEmail
.then
andotherwise
: Define the behavior fortrue
andfalse
values.
Integration with Formik
Here’s how to use the above schema with Formik:
import { Formik, Form, Field } from 'formik'
const MyForm = () => {
return (
<Formik
initialValues={{ showEmail: false, email: '' }}
validationSchema={validationSchema}
onSubmit={(values) => console.log(values)}
>
{({ errors, touched }) => (
<Form>
<label>
<Field type="checkbox" name="showEmail" /> Show Email
</label>
{touched.showEmail && (
<div>
<Field name="email" placeholder="Email" />
{errors.email && <div>{errors.email}</div>}
</div>
)}
<button type="submit">Submit</button>
</Form>
)}
</Formik>
)
}
export default MyForm
Common Pitfalls
- Undefined Initial Values: Always define initial values for all fields in
initialValues
. Without it, Yup won’t recognize the fields, leading to errors. - Nested Conditions: For nested validations, use a combination of
Yup.lazy
or functions inwhen
. - TypeScript Issues: Ensure proper typing by using
.concat
for merging schemas.
Advanced Use Cases
Validating Multiple Fields
You can validate multiple dependent fields using the when
method:
const schema = Yup.object().shape({
password: Yup.string().required('Password is required'),
confirmPassword: Yup.string().when('password', {
is: (password) => password && password.length > 0,
then: Yup.string().oneOf([Yup.ref('password')], 'Passwords must match'),
}),
})
when
Using a Function in For more complex conditions:
const schema = Yup.object().shape({
contactMethod: Yup.string().required('Contact method is required'),
phone: Yup.string().when('contactMethod', (method, schema) => {
return method === 'phone' ? schema.required('Phone number is required') : schema
}),
})
FAQs
when
method in Yup?
1. What is the The when
method allows you to define conditional validation logic based on other fields or values in the schema.
when
with nested objects?
2. Can I use Yes, use dot notation (e.g., parent.child
) or Yup.lazy
for deeply nested objects.
3. How do I handle multiple conditions?
You can combine multiple conditions using functions inside when
or use logical operators.
4. Why am I getting a "Cannot read property of undefined" error?
Ensure all fields have initial values in initialValues
when using Formik.
5. Can I validate an array conditionally?
Yes, use Yup.array().of()
with conditions applied to the inner schema.
Conclusion
Conditional validation in Yup is a flexible and powerful tool for managing dynamic forms. By understanding the when
method and its applications, you can create forms that are both user-friendly and robust.
For further exploration, check out the official Yup documentation.