Обработка ошибок из API с помощью Formik - PullRequest
1 голос
/ 28 июня 2019

Я ловлю ошибки из API и показываю их в форме, и это работает нормально.Но проблема в том, что когда я изменяю одно поле в форме, все ошибки исчезают.Для формы я использую Formik и для проверки Yup.

const handleSubmit = (values, {setSubmitting,  setFieldError, setStatus}) => {
    someApiCall(values)
        .then(
            () => {

            },
            (error) => {
                // example of setting error
                setFieldError('email', 'email is already used');
            })
        .finally(() => {
            setSubmitting(false)
        });
};

Я пытался добавить третий параметр false в setFieldError, но ничего не изменилось.

1 Ответ

1 голос
/ 29 июня 2019

Вот мой рабочий пример: https://codesandbox.io/s/formik-example-dynamic-server-rendered-values-1uv4l

В Formik доступен обратный вызов validate: https://jaredpalmer.com/formik/docs/api/formik#validate-values-values-formikerrors-values-promise-any, с помощью которого вы, вероятно, можете попытаться сделать что-то подобное ниже.

Я инициировал emailsAlreadyInUse с пустым массивом и затем в вашем вызове API, как только ошибка будет возвращена, затем добавьте этого пользователя в массив, и как только пользователь снова использует тот же адрес электронной почты и попытается проверить, хотя он пройдет проверку Yup, но это будет быть пойманным в validate обратном вызове, который, я полагаю, запускается после проверки Yup (хотя я могу ошибаться, но в вашем случае это не имеет значения).

const emailsAlreadyInUse= [];
const handleSubmit = (values, {
  setSubmitting,
  setFieldError,
  setStatus
}) => {
  someApiCall(values)
    .then(
      () => {
        // Do something
        // possibly reset emailsAlreadyInUse if needed unless component is going to be unmounted.
      },
      (error) => {
        // example of setting error
        setFieldError('email', 'email is already used');
        // Assuming error object you receive has data object that has email property
        emailsAlreadyInUse.push(error.data.email);
      })
    .finally(() => {
      setSubmitting(false)
    });
};

<Formik
...
...
validate = {
  values => {
    let errors = {};
    if (emailsAlreadyInUse.includes(values.email)) {
      errors.email = 'email is already used';
    }
    return errors;
  }
}
/>
...