Formik+Yup表单验证:数组内对象关联验证规则实现求助
Hey there! Let's tackle those remaining validation rules one by one. I've adjusted your Yup schema to cover all 5 requirements, with comments explaining each part so you can follow along easily.
First, let's recap the rules we need to implement beyond the first one you already have:
- Rule 2: If
bookingDurationhas items, everypriceinpricePerHoursmust be filled - Rule 3: If any
priceinpricePerHoursis filled,bookingDurationmust have at least one item - Rule 4: If
maxGameis set (not empty/zero), everypriceinpricePerGamemust be filled - Rule 5: If any
priceinpricePerGameis filled,maxGamemust be set (and greater than zero)
Here's the updated Yup schema with all rules enforced:
const schema = Yup.object().shape({ title: Yup.string() .min(2, 'Must be 2 characters or more') .required('Title is required'), schedules: Yup.array().of( Yup.object().shape({ // Rule 1 + Rule 3: Booking Duration validation bookingDuration: Yup.array() // Rule 3: Require bookingDuration if any pricePerHours.price is filled .when('reservationSlots', { is: (reservationSlots) => { // Check if any pricePerHours entry has a non-empty, non-whitespace price return reservationSlots?.some(slot => slot.pricePerHours?.some(pph => pph.price?.trim() !== '') ); }, then: Yup.array().min(1, 'Booking Duration is required when price per hour is set'), otherwise: Yup.array() }) // Rule 1: Require bookingDuration if maxGame is empty/zero .when('maxGame', { is: (val) => val === '' || val === null || val === 0, then: Yup.array().min(1, 'Booking Duration is required'), otherwise: Yup.array() }), // Rule 1 + Rule 5: Max Game validation maxGame: Yup.number() // Rule 5: Require maxGame if any pricePerGame.price is filled .when('reservationSlots', { is: (reservationSlots) => { // Check if any pricePerGame entry has a non-empty, non-whitespace price return reservationSlots?.some(slot => slot.pricePerGame?.some(ppg => ppg.price?.trim() !== '') ); }, then: Yup.number() .min(1, 'Max Game must be greater than zero when price per game is set') .required('Max Game is required when price per game is set'), otherwise: Yup.number() }) // Rule 1: Require maxGame if bookingDuration is empty .when('bookingDuration', { is: (bookingDuration) => bookingDuration.length === 0, then: Yup.number() .min(1, 'Max Game must be greater than zero') .required('Max Game is required either fill booking duration'), otherwise: Yup.number() }), reservationSlots: Yup.array().of( Yup.object().shape({ from: Yup.date().typeError('Invalid Time'), to: Yup.date().typeError('Invalid Time'), increment: Yup.string().required('Time Increment is required'), // Rule 2: Price Per Hours validation pricePerHours: Yup.array().of( Yup.object().shape({ guest: Yup.string(), price: Yup.string() // Rule 2: Require price if bookingDuration has items .when('../../../bookingDuration', { is: (bookingDuration) => bookingDuration?.length > 0, then: Yup.string().required('Price is required when booking duration is set'), otherwise: Yup.string() }) }) ), // Rule 4: Price Per Game validation pricePerGame: Yup.array().of( Yup.object().shape({ type: Yup.string(), price: Yup.string() // Rule 4: Require price if maxGame is set (non-empty/zero) .when('../../../maxGame', { is: (maxGame) => maxGame !== null && maxGame !== '' && maxGame >= 1, then: Yup.string().required('Price is required when max game is set'), otherwise: Yup.string() }) }) ), }) ) }, [['bookingDuration', 'maxGame']]) ) });
Quick breakdown of key changes:
- Cross-level field access: We use
../../../in thewhenclauses for price fields to reach up to the parentscheduleobject (since these price fields are nested 3 levels deep). - Whitespace handling: Added
trim() !== ''to ensure empty strings with whitespace are treated as invalid, making validation more robust. - Optional chaining: Used
?.to avoid errors if nested arrays/objects are undefined (adds safety even if your form structure changes slightly). - Rule combination: We kept your original Rule 1 logic and added new rules alongside it using additional
whenclauses, so all rules work together without conflicts.
This schema should now enforce all 5 validation rules you specified. Let me know if you need any tweaks or further clarification!
内容的提问来源于stack exchange,提问作者Tarni Baghel
相关产品推荐
相关产品推荐

