#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;
Шаги для воспроизведения:
- Заполните все поля и посмотрите консоль.войдите в систему с массивом ошибок или попробуйте отправить форму и проверить console.log
- Массив ошибок будет иметь один объект, даже если все поля действительны, и форма не будет отправлена из-за описанной проблемы
Ожидаемое поведение: после того, как все поля действительны, возвращаемый результат должен быть пустым массивом
Я создал этот 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]);