Как загрузить файл при обновлении события onChange?Javascript

Форум по Javascript
Ответить
Anonymous
 Как загрузить файл при обновлении события onChange?

Сообщение Anonymous »

Я использую Nextjs и Resend для отправки электронных писем из разных форм. Все мои формы отправляют данные без проблем, за исключением одной, которая предполагает загрузку файла.
Вот как я создаю свои формы.
У меня есть Компонент FormGroup:

Код: Выделить всё

"use client";
import { useEffect, useState } from "react";
type FormGroupProps = {
label?: string;
inputType?: "input" | "textarea" | "select" | "file";
inputProps?:
| React.InputHTMLAttributes
| React.TextareaHTMLAttributes;
selectOptions?: Array;
error?: string;
};

export default function FormGroup({
label,
inputType = "input",
inputProps,
selectOptions = [],
error,
}: FormGroupProps) {
const [hasError, setHasError] = useState(false);

useEffect(() => {
setHasError(error !== undefined);
}, [error]);

return (
className={`form-group flex flex-col h-full gap-2.5 ${
inputProps?.className || ""
}`}
>
{label && (

{label}

)}
{inputType === "input" && (

)}
{error && {error}}

{inputType === "textarea" && (

)}
{inputType === "file" && (

)}

{inputType === "select" && (

{selectOptions?.map((option) => (


{option.label}

))}

)}

);
}
Затем у меня есть компонент GenericForm:

Код: Выделить всё

"use client";
import React, { useState } from "react";
import FormGroup from "./FormGroup";
import FormTitle from "./FormTitle";

interface GenericFormProps {
title: string;
fields: Array;
onSubmit: (data: T) => void;
errors: { [key in keyof T]?: string };
handleChange?: (event: React.ChangeEvent) => void;
}

interface FormData {
nombre: string;
apellido: string;
dni: string;
celular: string;
mail: string;
comentarios: string;
cv?: {
name: string;
type: string;
base64: string;
};
}

function GenericForm({
title,
fields,
onSubmit,
errors,
handleChange,
}: GenericFormProps) {
const initialFormData = {} as T;
const [formData, setFormData] = useState(initialFormData);

const combinedHandleChange = (event: React.ChangeEvent) => {
if (handleChange) {
handleChange(event);
}
const { name, value, files } = event.target as HTMLInputElement &  {
files: FileList | null;
};
setFormData((prevData) => ({
...prevData,
[name]: files ? files[0] : value,
}));
};

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
onSubmit(formData);

if (!Object.values(errors).some((error) => error !== undefined)) {
setFormData(initialFormData);
}
};

return (




{fields.map((field, index) => (



))}



Enviar




);
}

export default GenericForm;
И форма, которая не работает, — это TrabajaConNosotros.tsx:

Код: Выделить всё

"use client";
import GenericForm from "./GenericForm";
import TrabajaConNosotrosSchema from "@/schemes/trabaja-con-nosotros.scheme";
import handleSubmit from "@/utils/submitForm";
import { useState } from "react";

const TrabajaConNosotros = () => {
const fields = [
{ label: "Nombre", inputType: "input", name: "nombre" },
{ label: "Apellido", inputType: "input", name: "apellido" },
{ label: "DNI (sin puntos)", inputType: "input", name: "dni" },
{ label: "Celular", inputType: "input", name: "celular" },
{ label: "Mail", inputType: "input", name: "mail" },
{ label: "Comentarios", inputType: "textarea", name: "comentarios" },
{ label: "Adjuntar CV", inputType: "file", name: "cv" },
];

const [errors, setErrors] = useState({});

const [selectedFile, setSelectedFile] = useState(null);

const handleChange = (event: React.ChangeEvent) => {
const file = event.target.files?.[0];
if (file) {
setSelectedFile(file);
}
};

const readFileAsync = (file: File): Promise =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});

const onSubmit = async (data: FormData) => {
if (selectedFile) {
try {
const base64 = await readFileAsync(selectedFile);
const formDataWithCV = {
...data,
cv: {
name: selectedFile.name,
type: selectedFile.type,
base64: base64.split(',')[1],
},
};

await handleSubmit(formDataWithCV, TrabajaConNosotrosSchema, 'trabajar_con_nosotros');
setErrors({});
} catch (err) {
console.error(err);
}
} else {
try {
await handleSubmit(data, TrabajaConNosotrosSchema, 'trabajar_con_nosotros');
setErrors({});
} catch (err) {
if (err.inner) {
const formErrors = err.inner.reduce((acc, currentError) =>  {
acc[currentError.path] = currentError.message;
return acc;
}, {});
setErrors(formErrors);
} else {
setErrors({ general: "Ha ocurrido un error desconocido" });
}
}
}
};

return (

);
};

export default TrabajaConNosotros;
Ошибка возникает, когда я выбираю файл для загрузки и сразу же на экране появляется следующая ошибка:

Код: Выделить всё

Uncaught DOMException: An attempt was made to use an object that is not, or is no longer, usable
Из этого сообщения об ошибке я предполагаю, что оно как-то связано с событием onChange, но понятия не имею, как это исправить.

Подробнее здесь: https://stackoverflow.com/questions/793 ... ange-event
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»