You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:34:54