javascript - 映射 Formik 文本字段
问题描述
我正在使用材料 ui 文本字段并使用 Formik 验证它们。我不想多次输入所有内容,而是想映射项目,但我无法这样做。
return (
<div>
<Formik
initialValues={{ email: '' }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
validationSchema={schema}>
{props => {
const {
values: { email },
errors,
touched,
handleChange,
isValid,
setFieldTouched,
} = props;
const change = (name: string, e: FormEvent) => {
e.persist();
handleChange(e);
setFieldTouched(name, true, false);
};
return (
<div className="main-content">
<form
style={{ width: '100%' }}
onSubmit={e => {
e.preventDefault();
submitForm(email);
}}>
<div>
<TextField
variant="outlined"
margin="normal"
id="email"
name="email"
helperText={touched.email ? errors.email : ''}
error={touched.email && Boolean(errors.email)}
label="Email"
value={email}
onChange={change.bind(null, 'email')}
/>
{/* {[{ variant:"outlined", margin:"normal", id:"email", name:"email", label: "Email", value: email, onChange:{change.bind(null, 'email')}
].map((item, index) => (
<TextField></TextField>
))} */}
<br></br>
<CustomButton
text={'Remove User'}
/>
</div>
</form>
</div>
);
}}
</Formik>
</div>
);
目前在注释掉的部分,我得到了change.bind
错误(property) change: (name: string, e: React.FormEvent<Element>) => void
',' expected.ts(1005)
同样,如果我尝试添加helperText:{touched.email ? errors.email : ''}
要映射到文本字段的参数列表,我会得到:
(property) touched: FormikTouched<{
email: string;
}>
',' expected.ts(1005)
上touched.email
。当我尝试使用时也是如此errors.
(property) touched: FormikTouched<{
email: string;
}>
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'FormikTouched<{ email: string; }>'.
No index signature with a parameter of type 'string' was found on type 'FormikTouched<{ email: string; }>'.ts(7053)
解决方案
谢谢你的沙盒。
根据您的沙箱,我已设法通过该map
功能进行字段迭代。
首先分离出独特的现场道具
- 属于输入的道具,例如
name
id
label
等。 - 属于组件的 props 等
variant
margin
handlers
。
你最终会得到 2 个对象。
(1)一个应该抽象到组件并保存在单独文件中的字段,您以后可以使用另一个组件中的字段。
这里因为你使用 formik 并且你需要有一个 formik 的引用键,所以我formikRef
在对象中添加了 。
const fileds = [
{
id: "email",
name: "email",
formikRef: "email",
label: "Email"
},
{
id: "name",
name: "name",
formikRef: "name",
label: "Name"
}
];
(2) 第二个应该存储在组件中的对象,因为它解析了<TextField/>
props
我通常将它们包装在 useMemo 钩子中,因此如果未更改依赖对象,则不应重新声明它。这仅用于性能,您也可以使用直接对象
const defaultProps = React.useMemo(() => ({
textField: {
variant: 'outlined',
margin: 'normal',
onChange: props => {
formik.handleChange(props);
formik.handleBlur(props);
},
onBlur: formik.handleBlur
}
}),
[formik]
);
//without useMemo
const defaultProps = {
textField: {
variant: 'outlined',
margin: 'normal',
onChange: props => {
formik.handleChange(props);
formik.handleBlur(props);
},
onBlur: formik.handleBlur
}
}
最后一步是在渲染中映射道具
{
fileds.map(({ formikRef, ...input }) => (
<TextField
key={formikRef}
helperText={getIn(formik.touched, formikRef) ? getIn(formik.errors, formikRef) : ''}
error={getIn(formik.touched, formikRef) && Boolean(getIn(formik.errors, formikRef))}
value={getIn(formik.values, formikRef)}
{...input}
{...defaultProps.textField}
/>
))
}
我还在这里创建了一个工作沙箱
LE:类型检查是一个问题,但可以通过一点搜索找到解决方案......在这里讨论过
为了通过类型检查问题,我进行了更正并添加了getIn
辅助函数。Formik
推荐阅读
- autodesk-forge - Autodesk Forge 清单仅返回缩略图,没有 guid - svf 作业未运行
- angularjs - 使用 $http 的服务不返回新数据
- python - 在 Python 中并发 set_secret 调用 Azure KeyVault API
- html - 如何在页面上居中背景图像?
- r - 如何使用 rapply 提取深度嵌套列表中的特定子级别?
- c++ - 如何从 python 序列化数百个字典和元组列表,以便将它们读入 C++ 函数
- php - 而在while循环中仅在PHP第一次时有效
- c - 如何在 C 包含语句中使用#define?
- postgresql - 恢复 PostgreSQL 数据库而不只转储数据库文件
- java - 如何使用 URL 从数据库中的表中打印多条记录