如何使用 React/Formik 和 Yup 验证将此对象嵌套在另一个对象中?
How can I nest this Obejct inside another using React/Formik and Yup validation?
我正在尝试学习如何使用 Formik 和 Yup 来验证输入(文本)表单域。我遵循了 Jared Palmer 的标准方法,开箱即用,效果很好。
当涉及到做更多组件驱动的事情时,我很难达到相同级别的验证,而且我无法弄清楚我哪里出错了?
是的,似乎无法识别我的表单模型,也不会按要求验证输入字段...
我在想我实际上搞砸了初始值,或者我没有以 Yup 正在寻找的正确形状提供它们,但是这里的任何帮助都会很棒,这让人发疯.. .
我有一个示例沙箱,运行 这里 > >
https://codesandbox.io/s/building-multi-step-form-with-formik-yup-vjzpk
表单模型
(components/CheckoutPage/FormModel/checkoutFormModel.js):
export default {
formId: "checkoutForm",
formField: {
nestedObj: {
firstName: {
name: "firstName",
label: "First name*",
requiredErrorMsg: "First name is required"
}
}
}
};
初始值
(components/CheckoutPage/FormModel/initialValues.js):
import checkoutFormModel from "./checkoutFormModel";
const {
formField: {
nestedObj: { firstName }
}
} = checkoutFormModel;
export default {
nestedObj: {
[firstName.name]: ""
}
};
是的验证模式
(components/CheckoutPage/FormModel/validationSchema.js):
import * as Yup from "yup";
import checkoutFormModel from "./checkoutFormModel";
const {
formField: {
nestedObj: { firstName }
}
} = checkoutFormModel;
export default [
Yup.object().shape({
nestedObj: Yup.object().shape({
[firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`)
})
})
];
结合了 Yup 和 Formik 的地址表
(components/CheckoutPage/Forms/AddressForm.js):
import React from "react";
import { Grid } from "@material-ui/core";
import { InputField } from "../../FormFields";
export default function AddressForm(props) {
const {
formField: {
nestedObj: { firstName }
}
} = props;
return (
<React.Fragment>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<InputField name={firstName.name} label={firstName.label} fullWidth />
</Grid>
</Grid>
</React.Fragment>
);
}
会发生什么,你的 yup 验证将验证像
这样的对象
{
nestedObj: {
[firstName.name]: '' // Validation will get here
}
}
但是当你传递给你的输入时 name={firstName.name}
你的输入会像
{
[firstName.name]: ''
}
所以你错过了验证,因为你在 yup 验证中添加了 nestedObj
或
您忘记将 nestedObj
添加到 firstName.name
。
因此,您可以将验证架构更改为
Yup.object().shape({
[firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`)
})
或
传递给输入,名字nestedObj
<InputField name={`nestedObj.${firstName.name}`} label={firstName.label} fullWidth />
您可以选择将其作为道具或硬编码字符串传递。
我正在尝试学习如何使用 Formik 和 Yup 来验证输入(文本)表单域。我遵循了 Jared Palmer 的标准方法,开箱即用,效果很好。
当涉及到做更多组件驱动的事情时,我很难达到相同级别的验证,而且我无法弄清楚我哪里出错了?
是的,似乎无法识别我的表单模型,也不会按要求验证输入字段...
我在想我实际上搞砸了初始值,或者我没有以 Yup 正在寻找的正确形状提供它们,但是这里的任何帮助都会很棒,这让人发疯.. .
我有一个示例沙箱,运行 这里 > >
https://codesandbox.io/s/building-multi-step-form-with-formik-yup-vjzpk
表单模型 (components/CheckoutPage/FormModel/checkoutFormModel.js):
export default {
formId: "checkoutForm",
formField: {
nestedObj: {
firstName: {
name: "firstName",
label: "First name*",
requiredErrorMsg: "First name is required"
}
}
}
};
初始值 (components/CheckoutPage/FormModel/initialValues.js):
import checkoutFormModel from "./checkoutFormModel";
const {
formField: {
nestedObj: { firstName }
}
} = checkoutFormModel;
export default {
nestedObj: {
[firstName.name]: ""
}
};
是的验证模式 (components/CheckoutPage/FormModel/validationSchema.js):
import * as Yup from "yup";
import checkoutFormModel from "./checkoutFormModel";
const {
formField: {
nestedObj: { firstName }
}
} = checkoutFormModel;
export default [
Yup.object().shape({
nestedObj: Yup.object().shape({
[firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`)
})
})
];
结合了 Yup 和 Formik 的地址表 (components/CheckoutPage/Forms/AddressForm.js):
import React from "react";
import { Grid } from "@material-ui/core";
import { InputField } from "../../FormFields";
export default function AddressForm(props) {
const {
formField: {
nestedObj: { firstName }
}
} = props;
return (
<React.Fragment>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<InputField name={firstName.name} label={firstName.label} fullWidth />
</Grid>
</Grid>
</React.Fragment>
);
}
会发生什么,你的 yup 验证将验证像
这样的对象{
nestedObj: {
[firstName.name]: '' // Validation will get here
}
}
但是当你传递给你的输入时 name={firstName.name}
你的输入会像
{
[firstName.name]: ''
}
所以你错过了验证,因为你在 yup 验证中添加了 nestedObj
或
您忘记将 nestedObj
添加到 firstName.name
。
因此,您可以将验证架构更改为
Yup.object().shape({
[firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`)
})
或
传递给输入,名字nestedObj
<InputField name={`nestedObj.${firstName.name}`} label={firstName.label} fullWidth />
您可以选择将其作为道具或硬编码字符串传递。