使用 Formik 和 Yup,如何显示嵌套对象字段的表单错误?

问题描述 投票:0回答:1

我正在使用 React 18、Ionic 7、Formik 2.4 和 Yup 0.32。我有一个带有嵌套对象的对象

export type Person = {
  name: string
  address: Address
}

地址 objectcdt 定义为

export type Address = {
  city: string
}

export default Address

我的 Yup 模式的定义类似

export const personValidationSchema = Yup.object({
  name: Yup.string().required('First Name is required'),
  address: addressValidationSchema
})

地址模式定义为

export const addressValidationSchema = Yup.object({
  city: Yup.string().required('City is required')
})

我不确定如何设置错误显示逻辑,以便在有人未在 Formik 表单中填写城市时显示错误。我有这个

        <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}

如果没有输入名称,错误显示得很好......

          <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}

我还需要做什么?这个不起作用的例子可以在这里找到—— https://stackblitz.com/edit/an5yjh-v3s4ke?file=src%2Fschemas%2Faddress-schema.ts,src%2Fcomponents%2FMyForm.tsx,src%2Fschemas%2Fperson-schema.ts,src%2FApp.tsx

reactjs formik yup nested-object ionic7
1个回答
0
投票

我查看了您发布的 stackblitz 示例,我发现的错误位于

MyForm
组件中。
initialFormValues
city

的拼写错误
 const initialFormValues: Person = {
    name: '',
    address: {
     ity: '', // this is the typo
    },
  };

这将是正确的修复方法

 const initialFormValues: Person = {
    name: '',
    address: {
     city: '', // this is the fix
    },
  };

这是完整的组件修复

import React, { useEffect, useRef, useState } from 'react';
import {
  IonList,
  IonItem,
  IonLabel,
  IonCheckbox,
  IonIcon,
  IonPage,
  IonContent,
  IonNote,
  IonButton,
  IonInput,
} from '@ionic/react';
import { pencilOutline } from 'ionicons/icons';
import Person from './types/person.type';
import { personValidationSchema } from '../schemas/person-schema';
import { Formik, FormikProps } from 'formik';

const MyForm: React.FC = () => {
  const formikRef = useRef<FormikProps<Person>>(null);
  const initialFormValues: Person = {
    name: '',
    address: {
      city: '',
    },
  };

  return (
    <Formik
      enableReinitialize={true}
      innerRef={formikRef}
      initialValues={initialFormValues}
      validationSchema={personValidationSchema}
      onSubmit={(values, { resetForm }) => {
        alert('Saved!');
      }}
    >
      {(formikProps) => (
        <form onSubmit={formikProps.handleSubmit}>
          <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}

          <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}

          <IonButton type="submit">Save</IonButton>
        </form>
      )}
    </Formik>
  );
};

export default MyForm;


© www.soinside.com 2019 - 2024. All rights reserved.