Yup всегда возвращает ошибку, даже если все поля действительны

#reactjs #validation #react-hooks #yup

#reactjs #проверка #реагирующие хуки #да

Вопрос:

Yup всегда возвращает одну ошибку в массиве, даже если все поля действительны. Проверка работает нормально, проверяет каждое поле и правильно отображает ошибки. Состояние формы и проверка контролируются с помощью приведенного ниже крючка реакции:

 import { useCallback, useEffect, useState } from "react";
import { contactSchema } from "./schema";

const useForm = () => {
const [values, setValues] = useState({});
const [touched, setTouched] = useState({});
const [errors, setErrors] = useState([]);

useEffect(() => {
 contactSchema
  .validate(values, { abortEarly: false, context: { value: "GR" } })
  .catch((err) => {
    const schemaErrors = err.inner?.map((err) => {
      return { field: err.path, message: err.message };
    });

    setErrors(schemaErrors);
  });
}, [values]);

const handleChange = (inputName) => (event) => {
 setValues({ ...values, [inputName]: event.target.value });
};

const handleBlur = (inputName) => () => {
 setTouched({ ...touched, [inputName]: true });
};

const canSubmit = () => {
 if (errors.length > 0) {
  errors.forEach((err) => {
    setTouched((prevState) => ({ ...prevState, [err.field]: true }));
  });
}

 return errors.length > 0;
};

const hasError = (field) => {
  let touchedField = null;
  const error = errors.find((fld) => fld.field === field);

  Object.keys(touched || {}).forEach((key) => {
   if (key === field amp;amp; touched[key]) {
    touchedField = touched[key];
    }
  });

  return touchedField ? error : null;
};

 return {values, handleChange, touched, handleBlur, errors, hasError, canSubmit};
};

export default useForm;
 

Шаги для воспроизведения:

  1. Заполните все поля и посмотрите консоль.войдите в систему с массивом ошибок или попробуйте отправить форму и проверить console.log
  2. Массив ошибок будет иметь один объект, даже если все поля действительны, и форма не будет отправлена из-за описанной проблемы

Ожидаемое поведение: после того, как все поля действительны, возвращаемый результат должен быть пустым массивом

Я создал этот codesandbox с полным кодом. Заранее спасибо за любую помощь!

Комментарии:

1. Решение состояло в том, чтобы очистить состояние внутри useEffect перед проверкой

Ответ №1:

Решение состоит в том, чтобы очищать состояние ошибки в useEffect при каждом запуске эффекта, как показано ниже:

 useEffect(() => {
 setErrors([]) // this line reset the error state every time the effect runs
 contactSchema
  .validate(values, { abortEarly: false, context: { value: "GR" } })
  .catch((err) => {
    const schemaErrors = err.inner?.map((err) => {
    return { field: err.path, message: err.message };
  });

  setErrors(schemaErrors);
 });
}, [values]);