React+Ionic中如何用Formik和Yup显示嵌套对象字段的表单错误?
问题描述
使用React 18、Ionic 7、Formik 2.4和Yup 0.32开发表单,定义了包含嵌套对象的类型:
export type Person = { name: string address: Address } export type Address = { city: string }
对应的Yup校验Schema:
export const addressValidationSchema = Yup.object({ city: Yup.string().required('City is required') }) export const personValidationSchema = Yup.object({ name: Yup.string().required('First Name is required'), address: addressValidationSchema })
当前表单中,name字段的错误提示正常显示,但city字段的错误无法正常展示,相关代码如下:
// City输入框及错误提示 <IonInput aria-label='City' placeholder='City' value={formikProps.values.address.city} onIonChange={(e) => formikProps.setFieldValue('address.city', e.detail.value)} name='address.city' /> {formikProps.touched.address.city && formikProps.errors.address.city ? ( <IonNote slot='error'>{formikProps.errors.address.city}</IonNote> ) : null} // Name输入框及错误提示(正常工作) <IonInput aria-label='Name' placeholder='Name' value={formikProps.values.name} onIonChange={(e) => formikProps.setFieldValue('name', e.detail.value)} name='name' /> {formikProps.touched.name && formikProps.errors.name ? ( <IonNote slot='error'>{formikProps.errors.name}</IonNote> ) : null}
解决方案
1. 手动标记嵌套字段的touched状态
Formik默认不会自动追踪嵌套字段的touched状态,需要在city输入框的失焦事件中手动标记:
<IonInput aria-label='City' placeholder='City' value={formikProps.values.address.city} onIonChange={(e) => formikProps.setFieldValue('address.city', e.detail.value)} onIonBlur={() => formikProps.setFieldTouched('address.city', true)} // 添加此行 name='address.city' />
2. 使用可选链避免空值报错
如果touched.address或errors.address未初始化,直接访问.city会导致报错,修改错误判断逻辑:
{formikProps.touched?.address?.city && formikProps.errors?.address?.city && ( <IonNote slot='error'>{formikProps.errors.address.city}</IonNote> )}
3. 确保初始化值正确
确认Formik的initialValues正确初始化嵌套对象,避免出现undefined:
const initialValues: Person = { name: '', address: { city: '' } };
4. 完善Yup校验规则(可选)
如果address字段本身为必填项,在根Schema中为其添加required约束,确保嵌套字段校验触发:
export const personValidationSchema = Yup.object({ name: Yup.string().required('First Name is required'), address: addressValidationSchema.required('Address is required') })
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

