【问题标题】:How to dynamically access nested errors/touched on formik Field如何动态访问嵌套错误/触及formik字段
【发布时间】: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}>{label}{required && '*'}</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 的错误和触摸对象上的必填字段,无论它是平面还是嵌套的?

【问题讨论】:

    标签: javascript reactjs twitter-bootstrap reactstrap 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>;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 2019-10-07
      • 1970-01-01
      • 2011-07-23
      相关资源
      最近更新 更多