Здравствуйте! Столкнулся со следующей проблемой:
1. нужно было сделать проверку валидности файла при использовании useForm, решил начать с одного параметра - веса. Написал функцию, а в документации нашел метод setError для последующей визуальной обработки ошибки.
2. Столкнулся с проблемой того, что errors в итоге пустой
3. При детальном разбере оказалось, что после загрузки файла и срабатывания ивента setError добавляет ошибку и по какой-то причине errors после этого очищается, я так понял, что это из за ререндеринга.
4. Нашел, что есть такие штуки, как useMemo и useCallback, но либо я их неправильно применил, либо дело в другом. Итог - errors остается пустым и пользователский выброс ошибки setError не сохраняется. Прошу добрых людей о помощи)
У меня уже глаз дергается....
function Upload( props ){
console.log("Rendering")
// объявление параметров
const types = props.allowTypes ? props.allowTypes : null
// ========
const {register, handleSubmit, setError, formState: {errors} } = useForm({mode: 'all'})
const id = useId()
//===============
const [fileName, setFileName] = useState("")
const [fileSize, setFileSize] = useState("")
const [step, setStep] = useState(1)
// =================
const uploadFile = async(values) =>{
const formData = new FormData();
formData.append("file", values.file[0]);
const { data } = await axios.post("/upload", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}})
console.log(data)
}
const onInputCallBack = useCallback((files) => {
if( files[0].size > 150 ){
setError('file', { type: 'custom', message: 'Недопустимый размер' });
}
setFileName(files[0].name);
setFileSize(files[0].size);
setStep( 2 )
}, [fileName, fileSize, step, errors])
return(
<form className={styles.form} onSubmit={ handleSubmit(uploadFile) }>
<div className={`${styles.step} ${styles.step1}`} active={(step === 1 ? "true": "false")}>
<label htmlFor={id}>Выберите файл</label>
<input type="file" id={id} {...register('file', { validate: (e) => onInputCallBack(e) } )}/>
<p className="rule">* Размером до 150 кб.</p>
</div>
<div className={`${styles.step} ${styles.step2}`} active={(step === 2 ? "true": "false")}>
<div className={styles.top}>
<div className={styles.name}>
<p>Название</p>
<span>{fileName}</span>
</div>
<div className={styles.size}>
<p>Размер</p>
<span>{fileSize} кб.</span>
</div>
</div>
{ errors.file ? <><label className={styles.send} errors="true" htmlFor={id}>Загрузить</label><input type="file" onInput={ onInputCallBack } id={id} {...register('file')}/></> : <input className={styles.send} type="submit" value="Отправить" errors=""/> }
<div className={styles.alert}>{ errors.file ? errors.file.message : "" }</div>
</div>
<div className={`${styles.step} ${styles.step3}`} active={(step === 3 ? "true": "false")}>
</div>
</form>
)
}
вот такой вот вывод получается: