如何动态访问嵌套错误/触及formik字段

Posted

技术标签:

【中文标题】如何动态访问嵌套错误/触及formik字段【英文标题】:How to dynamically access nested errors/touched on formik Field 【发布时间】:2019-09-29 00:56:23 【问题描述】:

我正在尝试创建一个 React 组件来抽象为我的表单创建一个输入组。所有输入都具有相同的布局 - 一个标签,下方是输入,如果存在错误/信息文本,这些将显示在输入下方。

以前我在处理自己的表单状态/处理程序。现在我正在尝试使用 formik(通过 Yup 验证)并且在我有嵌套信息时遇到了动态访问 errortouched 字段的问题。

这是我的输入组组件:

import React from 'react';
import  FormGroup, Label, Input, FormFeedback, FormText  from 'reactstrap';
import  Field, ErrorMessage  from 'formik';

const InputGroup = ( name, label, type, info, required ) => 
  return (
    <FormGroup>
      <Label htmlFor=name>labelrequired && '*'</Label>
      <Field name=name>
        (field, form) => (
          <Input ...field id=name type=
                 invalid=form.errors[name] && form.touched[name] //problem here
          />
        )
      </Field>
      info && <FormText color="muted">info</FormText>
      <ErrorMessage name=name>
          msg => <FormFeedback>msg</FormFeedback>
      </ErrorMessage>
    </FormGroup>
  )


InputGroup.propTypes = 
  label: PropTypes.string,
  name: PropTypes.string.isRequired,
  type: PropTypes.string,
  info: PropTypes.string,
  required: PropTypes.bool
;

InputGroup.defaultProps = 
  type: 'text',
  required: false
;

当我使用引导程序 (reactstrap@7.x) 时,&lt;FormFeedback&gt; 元素需要随附的 &lt;Input&gt; 标记为 invalid 标记。在上面我动态分配invalid=true/false,如果formik的form.errors对象上的相应字段存在(即存在错误)并且form.touched对象为真(即用户触摸了输入)。

当 formik 设置为平坦的 initialValues(例如下面)时,这可以正常工作,因为 invalid=form.errors[name] &amp;&amp; form.touched[name] 评估为(例如)invalid=form.errors[firstName] &amp;&amp; form.touched[firstName]

initialValues = 
  firstName: '',
  lastName: '',
  email: '',
  password: ''

但是,当 formik 设置有嵌套的 initialValues 时(例如,下面), invalid=form.errors[name] &amp;&amp; form.touched[name] 的计算结果为 invalid=form.errors[name.first] &amp;&amp; form.touched[name.first]。最终,这将始终评估为 false,因此输入始终为 invalid=false,因此输入永远不会标记错误样式,也不会显示错误消息。

initialValues = 
  name: 
    first: '',
    last: ''
  ,
  email: '',
  password: ''

如何设置我的 InputGroup 组件,以便我可以动态访问 formik 的错误和触摸对象上的必填字段,无论它是平面还是嵌套的?

【问题讨论】:

【参考方案1】:

Formik 有一个函数getIn(),它可以通过路径从对象中提取值(例如,路径类似于name.first)。

<Field name=name>
  ( field, form ) => (
    <Input
      ...field
      id=name
      invalid=getIn(form.errors, name) && getIn(form.touched, name)
    />
  )
</Field>

在 CodeSandbox 上查看 example here。

【讨论】:

优秀。我记得 Jared Palmer 在 youtube 上的 React Alicante 视频,formik 支持 lodash .get() 和点语法。最初使用 lodash,但最好有一个内置方法 - 可以使用更少的包。【参考方案2】:

Formik 还支持来自Field 组件的meta 参数,有为确切字段指定的信息(valuetouchederror)。

const CustomFormikInput = (props) =>    
    return <Field name=props.name>
       ( field, meta ) => 
            console.log(JSON.stringify(meta)); // Log meta output
            const errorMsg = meta.touched ? meta.error : undefined;
            return <div>
                     <input ...field ...props />
                     errorMsg
                   </div>;
        
    </Field>;

【讨论】:

以上是关于如何动态访问嵌套错误/触及formik字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在不创建其他字段的情况下生成一个列表的嵌套 formik 表单或表单字段?

如何在不提交的情况下访问 formik 字段的当前值?

在 for 循环期间访问嵌套对象 VueJS

如何在 useEffect 挂钩中形成 setFieldValue

如何使用 Retrofit2 处理嵌套 JsonObjects 的动态字段

ReactJS:如何使用动态键访问和更新嵌套状态对象?