简体   繁体   English

Formik 嵌套初始值、表单字段名称和点表示法?

[英]Formik nested initial values, form field names and dot notation?

TL:DR TL:博士

In formik, if I have a field name written in dot notation (for instance name="hands.left" ) which is linked to a property of a nested object in initialValues (for instance hands: {left: " ", right: " "} ), how can I use that field name when using validation errors, aka accessing object properties ( errors.hands.left and errors["hands.left"] don't work)在 formik 中,如果我有一个用点表示法编写的字段名称(例如name="hands.left" ),它链接到 initialValues 中嵌套 object 的属性(例如hands: {left: " ", right: " "} ),如何在使用验证错误时使用该字段名称,也就是访问 object 属性( errors.hands.lefterrors["hands.left"]不起作用)

As a consequence of my Typescript extended interface definitions, I have a dynamic Formik form with nested initialValues such as:由于我的 Typescript 扩展接口定义,我有一个动态 Formik 表单,其中包含嵌套的 initialValues,例如:

<Formik
  initialValues={{
    description: "",
    specialist: "",
    discharge: {
      date: "",
      criteria: "",
    },
// ...

The form fields attached to the nested values (discharge date and discharge criteria) is in the following shape:附加到嵌套值(出院日期和出院标准)的表单字段具有以下形状:

          <Field
            name="discharge.date"
            component={TextField}
          />

I use dot notation as that seems to be the only way of linking the field with my initial values, so that when text is entered, the initialValue discharge.date (so, the date property of the discharge object in initialValues) is modified.我使用点表示法,因为这似乎是将字段与我的初始值链接的唯一方法,因此当输入文本时,initialValue 放电.date(因此,initialValues 中放电 object 的日期属性)被修改。

But my problem comes when adding Formik validation:但是我的问题是在添加 Formik 验证时出现的:

validate={(values) => {    
          const requiredError = "Field is required";
          const errors: { [field: string]: string } = {};   

          if (!values.discharge.date) {
            errors.discharge.date = requiredError;
          }
          // ...

If I try to access the error with dot notation like that (errors.discharge.date), I get a warning saying "Property 'date' does not exist on type 'string'".如果我尝试使用这样的点符号 (errors.discharge.date) 访问错误,我会收到一条警告,提示“‘字符串’类型上不存在属性‘日期’”。

My solution was to change the field name from "discharge.date" to "dischargeDate":我的解决方案是将字段名称从“discharge.date”更改为“dischargeDate”:

      <Field
        name="dischargeDate"
        component={TextField}
      />

and

      if (!values.discharge.date) {
        errors.dischargeDate = requiredError;
      }

Which does work for the error object, but disconnects the field from my initial value (discharge>date), so when I enter text in the field, instead of changing the state of the nested object value (discharge.date) a new separate variable "dischargeDate" is created:这确实适用于错误 object,但会断开该字段与我的初始值(放电>日期)的连接,因此当我在字段中输入文本时,而不是更改嵌套 ZA8CFDE6331BD59EB2AC96F8911C4B6 值的 state (discharge.date)一个新的变量 66创建“放电日期”:

在此处输入图像描述

What am I supposed to do when naming the field to access both the nested initialValue (initialValues>discharge>date) and the error object properties?命名字段以访问嵌套的初始值(初始值>放电>日期)和错误 object 属性时,我应该怎么做? (errors.discharge.date) Is the only solution to rename my Typescript types? (errors.discharge.date) 是重命名我的 Typescript 类型的唯一解决方案吗?

interface BaseEntry {
  description: string;
  specialist: string;
}

interface Discharge {
  date: string;
  criteria: string;
}

export interface HospitalEntryType extends BaseEntry {
  discharge: Discharge;
}
import { FormikErrors } from 'formik';

interface BaseEntry {
  description: string;
  specialist: string;
}

interface Discharge {
  date: string;
  criteria: string;
}

export interface HospitalEntryType extends BaseEntry {
  discharge: Discharge;
}

interface FormValues extends HospitalEntryType {}

validate = (values: FormValues) => {
  let errors: FormikErrors<FormValues> = {};
  const requiredError = "Field is required";
  
  if (!values.discharge.date) {
    errors = { 
      discharge: {
        date: requiredError
      }
    }
  }

  return errors;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM