如何在 formik 字段上动态访问嵌套的 errors/touched
How to dynamically access nested errors/touched on formik Field
我正在尝试创建一个 React 组件来抽象化为我的表单创建一个输入组。所有输入都有相同的布局 - 一个标签,下面是输入,如果存在 errors/info 文本,这些文本将显示在输入下方。
之前我处理的是我自己的表格state/handlers。现在我正在尝试使用 formik(使用 Yup 验证)并且在我有嵌套信息时 运行 遇到动态访问 error
和 touched
字段的问题。
这是我的输入组组件:
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
};
由于我使用的是 bootstrap (reactstrap@7.x),<FormFeedback>
元素需要随附的 <Input>
标记 invalid
标签.在上面,如果 formik 的 form.errors
对象上的相应字段存在(即存在错误)并且 form.touched
对象为真(即用户触摸了输入),我动态分配 invalid=true/false
.
当 formik 设置为平坦的初始值(例如下面)时,这工作正常,因为 invalid={form.errors[name] && form.touched[name]}
评估为(例如)invalid={form.errors[firstName] && form.touched[firstName]}
initialValues = {
firstName: '',
lastName: '',
email: '',
password: ''
}
但是,当使用嵌套的 initialValues(例如下面)设置 formik 时,
invalid={form.errors[name] && form.touched[name]}
的计算结果为 invalid={form.errors[name.first] && form.touched[name.first]}
。最终,这将始终评估为 false,因此输入始终为 invalid=false
,因此输入永远不会标记错误样式或显示错误消息。
initialValues = {
name: {
first: '',
last: ''
},
email: '',
password: ''
}
如何设置我的 InputGroup 组件,以便我可以动态访问 formik 的错误和触摸对象的必填字段,无论它是平面的还是嵌套的?
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。
Formik 还支持来自 Field
组件的 meta
参数,有为确切字段指定的信息(value
、touched
、error
) .
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>;
}
我正在尝试创建一个 React 组件来抽象化为我的表单创建一个输入组。所有输入都有相同的布局 - 一个标签,下面是输入,如果存在 errors/info 文本,这些文本将显示在输入下方。
之前我处理的是我自己的表格state/handlers。现在我正在尝试使用 formik(使用 Yup 验证)并且在我有嵌套信息时 运行 遇到动态访问 error
和 touched
字段的问题。
这是我的输入组组件:
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
};
由于我使用的是 bootstrap (reactstrap@7.x),<FormFeedback>
元素需要随附的 <Input>
标记 invalid
标签.在上面,如果 formik 的 form.errors
对象上的相应字段存在(即存在错误)并且 form.touched
对象为真(即用户触摸了输入),我动态分配 invalid=true/false
.
当 formik 设置为平坦的初始值(例如下面)时,这工作正常,因为 invalid={form.errors[name] && form.touched[name]}
评估为(例如)invalid={form.errors[firstName] && form.touched[firstName]}
initialValues = {
firstName: '',
lastName: '',
email: '',
password: ''
}
但是,当使用嵌套的 initialValues(例如下面)设置 formik 时,
invalid={form.errors[name] && form.touched[name]}
的计算结果为 invalid={form.errors[name.first] && form.touched[name.first]}
。最终,这将始终评估为 false,因此输入始终为 invalid=false
,因此输入永远不会标记错误样式或显示错误消息。
initialValues = {
name: {
first: '',
last: ''
},
email: '',
password: ''
}
如何设置我的 InputGroup 组件,以便我可以动态访问 formik 的错误和触摸对象的必填字段,无论它是平面的还是嵌套的?
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。
Formik 还支持来自 Field
组件的 meta
参数,有为确切字段指定的信息(value
、touched
、error
) .
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>;
}