首页 > 解决方案 > 无法在 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),我真的想不通。

谢谢您的帮助

标签: javascriptreactjsvalidationasynchronousformik

解决方案


到现在为止,我一直在为此工作一整天,最后,我解决了它。

如果您 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 上发布解决方案。

谢谢!


推荐阅读