onChange просто не работает при загрузке файлов в инпут, но если убрать {...register('avatar')}, то всё работает.
Вот код компонента загрузки аватара:
const UploadAvatar = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(({ ...props }, ref) => {
const avatarUrl = useSelector(userDataSelector)?.avatarUrl;
const [previewUrl, setPreviewUrl] = useState<string>('');
const [sizeError, setSizeError] = useState<boolean>(false);
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0];
if (file && file.size > 2 * 1024 * 1024) {
setSizeError(true);
return;
}
setPreviewUrl(file ? URL.createObjectURL(file) : '');
setSizeError(false);
}
return (
<div className={styles.upload}>
{avatarUrl &&
<>
<Image
className={styles.upload__avatar}
src={previewUrl ? previewUrl : avatarUrl}
alt="avatar"
width={120}
height={120}
/>
<label className={styles.upload__label}>
<input
ref={ref}
onChange={(e) => handleFileChange(e)}
{...props}
/>
<Image
src={'/icons/photo.svg'}
width={24}
height={24}
alt=''
/>
</label>
</>
}
{sizeError &&
<span className={styles.upload__error}>
File should be at least 2MB
</span>
}
</div>
)
})
Вот сама форма:
const schema = Joi.object({
avatar: Joi.object(),
username: Joi.string().min(5).max(16).required().pattern(/^(?=.*[a-zA-Z])[a-zA-Z0-9]+$/).messages({
'string.empty': 'Username is required',
'string.min': 'Too short',
'string.max': 'Too long',
'string.pattern.base': 'Username should be least at one character',
})
});
const onSubmit: SubmitHandler<TFormValues> = async (data) => {
console.log(data);
try {
// await signUp(data);
// router.push('/home');
} catch (err: any) {
console.error(err);
}
}
return (
<form
className={styles.form}
encType="multipart/form-data"
onSubmit={handleSubmit(onSubmit)}
>
<UploadAvatar
{...register('avatar')}
type="file"
accept="image/*"
/>
<InputField
required
type='text'
placeholder='Username'
error={errors.username?.message}
{...register('username')}
/>
<Button
variant='primary'
size='lg'
type='submit'
disabled={!isValid}
>
Done
</Button>
</form>
)