javascript - 无法在 Formik onSubmit 中设置错误
问题描述
这几天我遇到了一些问题,我在 Formik 表单的 onSubmit 方法中设置的每个错误都没有添加到错误道具中。我的具体问题是关于 GraphQL API 返回的后端错误。我有一个很长的表格,所以我不会发布我的所有代码,但相关代码如下:
这是我的表单的一个片段:
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
{({ errors, setFieldValue, touched, values }) => (
<>
{console.log(errors)}
<Form>
<div className="divided-by-2">
<div className="street-number-and-street">
<FormikTextField
id="streetNumber"
name="streetNumber"
label={i18next.t('model:traveler.streetNumber')}
/>
<FormikTextField
id="street"
name="street"
label={i18next.t('model:traveler.street')}
/>
</div>
<FormikTextField
id="city"
name="city"
label={i18next.t('model:traveler.city')}
/>
<FormikTextField
id="zip"
name="zip"
label={i18next.t('model:traveler.postCode')}
/>
</div>
</Form>
</>
)}
</Formik>
onSubmit 是我在 Formik 声明之外声明的函数,因为它非常广泛。它如下:
const onSubmit = async (values, actions) => {
const variables = {
firstname: values.firstname,
lastname: values.lastname,
[The rest of my variables are also here including the ones in the above snippet]
}
const { data } = await profileUpdate({
variables,
});
if (data.userUpdate.errors.length === 0) {
const { data } = await usersRoleRequestCreate({
variables: {
role: 'explorer',
note: values.note,
token,
},
});
if (data?.usersRoleRequestCreate?.errors.length > 0) {
for (const error of data?.usersRoleRequestCreate?.errors) {
console.log(error.attribute);
const key = Mapping[error.attribute];
if (key) {
let message = '';
for (const errorMessage of error.errors) {
message += errorMessage.message;
}
actions.setFieldError(key, message)
}
}
} else {
[If no errors, success code here]
}
}
}
我尝试使用 setFieldError,如此处所示,但我也尝试使用 setErrors,使用 useState 创建一个对象来存储我的后端验证错误,然后将这些值分配给错误,所有这些都失败了。错误具有值的唯一事件是当我从 yup 验证模式收到前端错误时。Formik 文档没有提供很多示例(https://formik.org/docs/api/formik),我真的想不通。
谢谢您的帮助
解决方案
到现在为止,我一直在为此工作一整天,最后,我解决了它。
如果您 setFieldError 然后执行验证功能,这些错误将被覆盖。我不知道这是否是最好的解决方案,但对我来说正在工作。
const validate = (values) => {
// let prevErr = formik.errors;
const errors = {};
console.log("inside validate", formik);
if (!values.email) {
if (!formik.errors.email) {
errors.email = "Required";
} else {
errors.email = formik.errors.email;
}
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
) {
errors.email = "Invalid email address";
}
if (!values.password) {
if (!formik.errors.email) {
errors.password = "Required";
} else {
errors.password = formik.errors.password;
}
}
return errors;
};
const onError = (data) => {
formik.setFieldError("email", "BackEnd Error");
formik.setFieldError("password", "BackEnd Error");
};
尝试寻找解决方案的方法:
- 初始值,必须设置
- Console.log 验证函数内的表单以查看您设置的错误何时加载到表单上。
- 看看字段是否被触摸
- 也许验证函数执行了两次以上,最终会覆盖这些错误,因为它们不再存在。
让我知道这是否可行,这是我第一次在 Stack Overflow 上发布解决方案。
谢谢!
推荐阅读
- batch-file - RENAME 函数不在批处理脚本中重命名
- javascript - Jquery 在 td 中创建带有字典条目的 html 表
- azure - 通过 HTTP 端点触发时,带有 enqueueTimeUtc 参数的 ServiceBusTrigger 失败
- mysql - 用户'root'@'external ip'的访问被拒绝(使用密码:是)
- javascript - Azure 存储 Javascript 库“createBlobServiceWithSas”引发错误:拒绝设置不安全的标头“用户代理”
- r - 减少一棵树的节点数,以获得具有多个子节点的节点
- sql - SQL Where 查询字符串中的列值
- python - 通过应用动态地将列添加到数据框
- mysql - 如何在一列中选择具有相同值但在另一列中彼此之间必须不同的行
- php - [Dialogflow]通过 Webhook 格式更新权限(用于推送通知)