Primero, revisa mi código.
¡Puede haber alguna falta de ortografía! (Reescribí mi código)
const test = () => { const [files, setFiles] = useState([]); const handleFile = (e) => { for(let i=0; i<e.target.files.length; i++){ setFiles([...files, e.target.files[i] } } return ( { files.map((file, index) => ( <div key={index}> <p> {file[index].name} </p> <button> Delete </button> </div> )) } <label onChange={handleFile}> <input type='file' mutiple /> Attach File </label> ) }Cuando renderizo con este código, comete errores,
TypeError: no se pueden leer las propiedades de undefined (leyendo 'nombre')
{archivo[índice].nombre}
como esto.
Cuando elimino .name, solo se representan los botones. (ya que no especifiqué qué renderizar de la propiedad del archivo).
Además, estoy tratando de renderizar varios archivos a la vez. Como configuro mi tipo de entrada como múltiple , puedo seleccionar varios archivos cuando elijo cargar cosas.
Sin embargo, aunque seleccioné dos o tres, solo muestra uno.
Espero que mi explicación describa bien mi situación. Si tiene alguna pregunta, ¡pregúnteme!
¡Tengo ganas de oír de usted!
Si actualiza el mismo estado varias veces en la misma función de controlador, solo la última llamada funcionará por problemas de rendimiento. Tienes que cambiar tu controlador onChange a algo como:
const handleFile = (e) => { const newFiles = [] for(let i = 0; i < e.target.files.length; i++){ newFiles.push(e.target.files[i]) } setFiles(newFiles) }también como se menciona en otra respuesta, cambie la línea "nombre" a esto:
<p>{file.name}</p>Para cualquiera que tenga el mismo problema que yo, aquí hay una solución provisional.
const [files, setFiles] = useState([]); const handleFile = (e) => { setFiles([...files, e.target.files[0], e.target.files[1], e.target.files[2]]) if(e.target.files[1] == null) { setFiles([...files, e.target.files[0]]) } if (e.target.files[1] && e.target.files[2] == null) { setFiles([...files, e.target.files[0], e.target.files[1]]) } };Usando la declaración condicional, puede controlar el índice de archivos. Sin embargo, todavía no sé cuál es la otra forma de lidiar con el problema.
De todos modos, ¡espero que mi respuesta te ayude un poco!
No estoy seguro de si me estoy perdiendo algo, pero creo que hacer un bucle como este es redundante cuando, en cambio, simplemente puede hacer
const handleFile = (e) => { setFiles(e.target.files) }Además, cuando desee acceder al valor del estado anterior, probablemente debería acceder al valor del estado anterior mediante una función de devolución de llamada dentro de setFiles como este
for(let i=0; i<e.target.files.length; i++){ setFiles((prevfiles)=>[...prevFiles,e.target.files[i]]) }EDITAR: también menciono una solución que no está incluida en la respuesta original, ya que @Matt ya la había declarado en el momento de la publicación. Estoy editando esta respuesta solo con el fin de proporcionar la respuesta completa
file[index].name tuvo que ser cambiado a file.name