Uso <input type="file" accept=".txt" />
con la propiedad accept. Lo configuré para aceptar, por ejemplo, solo archivos .txt
. Y funciona bien si hace clic en input
y abre el selector y no puede cargar archivos que no están permitidos por accept
.
Pero, cuando carga archivos drag & drop
, carga cualquier archivo ignorando accept
.
Aquí hay un ejemplo: https://codesandbox.io/s/floral-tdd-11wt9?file=/src/App.js
Para reproducir el problema:
.txt
P: ¿Cuál es la mejor manera de solucionar esto? Teniendo en cuenta que podría haber cualquier tipo de archivo y el tipo de archivo estándar file.type
información excesiva sobre el tipo de archivo.
Cuando agrega la aceptación, el navegador le dice al sistema operativo que muestre solo los archivos que se mencionan pero el soporte, pero cuando arrastra y suelta esta característica se elimina. La mejor manera es escribir una función de validación que verifique si el dado archivo es compatible o no como
const handleChange = (e) => { const newFiles = e.target.files; const fileName = newFiles[0].name; const extension = fileName.split(".").pop(); const isSupported = ["txt"].includes(extension); if (!isSupported) { alert("not supported"); setFiles(null); e.target.value = null; } else { setFiles(newFiles); }
};
aquí la ventaja de usar ["txt"].includes(extension)
es que, puede agregar validación para múltiples tipos de archivos, simplemente restablezco la entrada con e.target.value = null;
(cuando el archivo no es válido), pero puede usar su propia lógica allí
aquí hay un ejemplo de trabajo
Para evitar eliminar archivos no aceptados, debe agregar el controlador onDrop
para la entrada:
<input type="file" onDrop={handleDrop} accept="text/plain" {...otherProps} />
En onDrop
, compruebe si se acepta el tipo de archivo soltado:
const handleDrop = (e) => { const allowedTypes = new Set([e.target.accept]); if (!allowedTypes.has(e.dataTransfer.files[0].type)) { // stop event prepagation e.preventDefault(); } };
Aquí hay un ejemplo en vivo: